コード例 #1
0
static void
test_add_connection (void)
{
	NMConnection *connection;
	time_t start, now;
	gboolean done = FALSE;

	connection = nmtst_create_minimal_connection (TEST_CON_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);

	nm_client_add_connection_async (client,
	                                connection,
	                                TRUE,
	                                NULL,
	                                add_cb,
	                                &done);

	start = time (NULL);
	do {
		now = time (NULL);
		g_main_context_iteration (NULL, FALSE);
	} while ((done == FALSE) && (now - start < 5));
	g_assert (done == TRUE);
	g_assert (remote != NULL);

	/* Make sure the connection is the same as what we added */
	g_assert (nm_connection_compare (connection,
	                                 NM_CONNECTION (remote),
	                                 NM_SETTING_COMPARE_FLAG_EXACT) == TRUE);
	g_object_unref (connection);
}
コード例 #2
0
static void
test_nat_export (NMVpnPluginUiInterface *plugin,
                 const char *dir,
                 const char *tmpdir,
                 const char *nat_mode)
{
	NMConnection *connection;
	NMSettingVPN *s_vpn;
	NMConnection *reimported;
	char *path;
	gboolean success;
	GError *error = NULL;
	int ret;

	connection = get_basic_connection ("nat-export", plugin, dir, "basic.pcf");
	ASSERT (connection != NULL, "nat-export", "failed to import connection");

	s_vpn = nm_connection_get_setting_vpn (connection);
	ASSERT (s_vpn != NULL, "nat-export", "imported connection had no VPN setting");

	nm_setting_vpn_add_data_item (s_vpn, NM_VPNC_KEY_NAT_TRAVERSAL_MODE, nat_mode);

	path = g_build_path ("/", tmpdir, NAT_EXPORTED_NAME, NULL);
	success = nm_vpn_plugin_ui_interface_export (plugin, path, connection, &error);
	if (!success) {
		if (!error)
			FAIL ("nat-export", "export failed with missing error");
		else
			FAIL ("nat-export", "export failed: %s", error->message);
	}

	/* Now re-import it and compare the connections to ensure they are the same */
	reimported = get_basic_connection ("nat-export", plugin, tmpdir, NAT_EXPORTED_NAME);
	ret = unlink (path);
	ASSERT (connection != NULL, "nat-export", "failed to re-import connection");

	/* Clear secrets first, since they don't get exported, and thus would
	 * make the connection comparison below fail.
	 */
	remove_user_password (connection);

	/* Since we don't export the user password, but the original connection
	 * had one, we need to add secret flags to the re-imported connection.
	 */
	s_vpn = nm_connection_get_setting_vpn (reimported);
	nm_setting_set_secret_flags (NM_SETTING (s_vpn),
	                             NM_VPNC_KEY_SECRET,
	                             NM_SETTING_SECRET_FLAG_AGENT_OWNED,
	                             NULL);

	ASSERT (nm_connection_compare (connection, reimported, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
	        "nat-export", "original and reimported connection differ");

	g_object_unref (reimported);
	g_object_unref (connection);
	g_free (path);
}
コード例 #3
0
static void
test_add_connection (void)
{
	gs_unref_object NMConnection *connection = NULL;
	NMSettingConnection *s_con;
	NMSettingWired *s_wired;
	char *uuid;
	gboolean success;
	time_t start, now;
	gboolean done = FALSE;

	connection = nm_connection_new ();

	s_con = (NMSettingConnection *) nm_setting_connection_new ();
	uuid = nm_utils_uuid_generate ();
	g_object_set (G_OBJECT (s_con),
	              NM_SETTING_CONNECTION_ID, TEST_CON_ID,
	              NM_SETTING_CONNECTION_UUID, uuid,
	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
	              NULL);
	g_free (uuid);
	nm_connection_add_setting (connection, NM_SETTING (s_con));

	s_wired = (NMSettingWired *) nm_setting_wired_new ();
	nm_connection_add_setting (connection, NM_SETTING (s_wired));

	success = nm_remote_settings_add_connection (settings,
	                                             connection,
	                                             add_cb,
	                                             &done);
	g_assert (success == TRUE);

	start = time (NULL);
	do {
		now = time (NULL);
		g_main_context_iteration (NULL, FALSE);
	} while ((done == FALSE) && (now - start < 5));
	g_assert (done == TRUE);
	g_assert (remote != NULL);

	/* Make sure the connection is the same as what we added */
	g_assert (nm_connection_compare (connection,
	                                 NM_CONNECTION (remote),
	                                 NM_SETTING_COMPARE_FLAG_EXACT) == TRUE);
}
コード例 #4
0
static void
dispose (GObject *object)
{
	NMBluezDevice *self = NM_BLUEZ_DEVICE (object);
	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
	NMConnection *to_delete = NULL;

	if (priv->pan_connection) {
		/* Check whether we want to remove the created connection. If so, we take a reference
		 * and delete it at the end of dispose(). */
		if (   nm_settings_connection_get_unsaved (NM_SETTINGS_CONNECTION (priv->pan_connection))
		    && nm_connection_compare (priv->pan_connection, priv->pan_connection_original, NM_SETTING_COMPARE_FLAG_EXACT))
			to_delete = g_object_ref (priv->pan_connection);

		priv->pan_connection = NULL;
		g_clear_object (&priv->pan_connection_original);
	}

	g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self);
	g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_removed, self);
	g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_updated, self);

	g_slist_free_full (priv->connections, g_object_unref);
	priv->connections = NULL;

	g_clear_object (&priv->adapter5);
	g_clear_object (&priv->dbus_connection);

	G_OBJECT_CLASS (nm_bluez_device_parent_class)->dispose (object);

	if (to_delete) {
		nm_log_dbg (LOGD_BT, "bluez[%s] removing Bluetooth connection for NAP device: '%s' (%s)", priv->path,
		            nm_connection_get_id (to_delete), nm_connection_get_uuid (to_delete));
		nm_settings_connection_delete (NM_SETTINGS_CONNECTION (to_delete), NULL, NULL);
		g_object_unref (to_delete);
	}
}
コード例 #5
0
static void
reload_connections (gpointer config)
{
	SCPluginIfnet *self = SC_PLUGIN_IFNET (config);
	SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
	GList *conn_names = NULL, *n_iter = NULL;

	/* save names for removing unused connections */
	GHashTable *new_conn_names = NULL;
	GHashTableIter iter;
	gpointer key;
	gpointer value;

	if (priv->unmanaged_well_known)
		return;

	if (!reload_parsers ())
		return;
	PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections");
	conn_names = ifnet_get_connection_names ();
	new_conn_names =
	    g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
	for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) {
		NMIfnetConnection *exported;
		NMIfnetConnection *old;
		gchar *conn_name = g_strdup (n_iter->data);

		/* add the new connection */
		exported = nm_ifnet_connection_new (conn_name);
		if (!exported) {
			g_free (conn_name);
			continue;
		}
		g_signal_connect (G_OBJECT (exported), "ifnet_setup_monitors",
				  G_CALLBACK (setup_monitors), config);
		g_signal_connect (G_OBJECT (exported), "ifnet_cancel_monitors",
				  G_CALLBACK (cancel_monitors), config);
		old = g_hash_table_lookup (priv->config_connections, conn_name);
		if (old && exported) {
			gchar *auto_refresh =
			    ifnet_get_global_setting (IFNET_KEY_FILE_GROUP,
						      "auto_refresh");

			if (auto_refresh && is_true (auto_refresh)) {
				if (!nm_connection_compare (NM_CONNECTION (old),
							    NM_CONNECTION
							    (exported),
							    NM_SETTING_COMPARE_FLAG_EXACT))
				{
					PLUGIN_PRINT (IFNET_PLUGIN_NAME,
						      "Auto refreshing %s",
						      conn_name);
					g_signal_emit_by_name (old,
							       NM_SETTINGS_CONNECTION_INTERFACE_REMOVED);
					g_hash_table_remove
					    (priv->config_connections,
					     conn_name);
					g_hash_table_insert
					    (priv->config_connections,
					     g_strdup (conn_name), exported);
					if (is_managed (conn_name))
						g_signal_emit_by_name (self,
								       NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
								       exported);
				}
			} else
				update_old_connection (conn_name, old,
						       exported, priv);
			g_signal_emit_by_name (self,
					       NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
		} else if (exported) {
			g_hash_table_insert (priv->config_connections,
					     g_strdup (conn_name), exported);
			if (is_managed (conn_name))
				g_signal_emit_by_name (self,
						       NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
						       exported);
		}
		g_hash_table_insert (new_conn_names, conn_name, conn_name);
	}
	/* remove unused connections */
	g_hash_table_iter_init (&iter, priv->config_connections);
	while (g_hash_table_iter_next (&iter, &key, &value)) {
		if (!g_hash_table_lookup (new_conn_names, key)) {
			g_signal_emit_by_name (value,
					       NM_SETTINGS_CONNECTION_INTERFACE_REMOVED);
			g_hash_table_remove (priv->config_connections, key);
		}
	}
	g_hash_table_remove_all (new_conn_names);
	g_hash_table_destroy (new_conn_names);
	g_list_free (conn_names);
}
static NMIfcfgConnection *
update_connection (SCPluginIfcfg *self,
                   NMConnection *source,
                   const char *full_path,
                   NMIfcfgConnection *connection,
                   gboolean protect_existing_connection,
                   GHashTable *protected_connections,
                   GError **error)
{
	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
	NMIfcfgConnection *connection_new;
	NMIfcfgConnection *connection_by_uuid;
	GError *local = NULL;
	const char *new_unmanaged = NULL, *old_unmanaged = NULL;
	const char *new_unrecognized = NULL, *old_unrecognized = NULL;
	gboolean unmanaged_changed = FALSE, unrecognized_changed = FALSE;
	const char *uuid;

	g_return_val_if_fail (!source || NM_IS_CONNECTION (source), NULL);
	g_return_val_if_fail (full_path || source, NULL);

	if (full_path)
		_LOGD ("loading from file \"%s\"...", full_path);

	/* Create a NMIfcfgConnection instance, either by reading from @full_path or
	 * based on @source. */
	connection_new = nm_ifcfg_connection_new (source, full_path, error);
	if (!connection_new) {
		/* Unexpected failure. Probably the file is invalid? */
		if (   connection
		    && !protect_existing_connection
		    && (!protected_connections || !g_hash_table_contains (protected_connections, connection)))
			remove_connection (self, connection);
		return NULL;
	}

	uuid = nm_connection_get_uuid (NM_CONNECTION (connection_new));
	connection_by_uuid = g_hash_table_lookup (priv->connections, uuid);

	if (   connection
	    && connection != connection_by_uuid) {

		if (   (protect_existing_connection && connection_by_uuid != NULL)
		    || (protected_connections && g_hash_table_contains (protected_connections, connection))) {
			NMIfcfgConnection *conflicting = (protect_existing_connection && connection_by_uuid != NULL) ? connection_by_uuid : connection;

			if (source)
				_LOGW ("cannot update protected connection "NM_IFCFG_CONNECTION_LOG_FMT" due to conflicting UUID %s", NM_IFCFG_CONNECTION_LOG_ARG (conflicting), uuid);
			else
				_LOGW ("cannot load %s due to conflicting UUID for "NM_IFCFG_CONNECTION_LOG_FMT, full_path, NM_IFCFG_CONNECTION_LOG_ARG (conflicting));
			g_object_unref (connection_new);
			g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
			                     "Cannot update protected connection due to conflicting UUID");
			return NULL;
		}

		/* The new connection has a different UUID then the original one that we
		 * are about to update. Remove @connection. */
		remove_connection (self, connection);
	}

	/* Check if the found connection with the same UUID is not protected from updating. */
	if (   connection_by_uuid
	    && (   (!connection && protect_existing_connection)
	        || (protected_connections && g_hash_table_contains (protected_connections, connection_by_uuid)))) {
		if (source)
			_LOGW ("cannot update connection due to conflicting UUID for "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_by_uuid));
		else
			_LOGW ("cannot load %s due to conflicting UUID for "NM_IFCFG_CONNECTION_LOG_FMT, full_path, NM_IFCFG_CONNECTION_LOG_ARG (connection_by_uuid));
		g_object_unref (connection_new);
		g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
		                      "Skip updating protected connection during reload");
		return NULL;
	}

	/* Evaluate unmanaged/unrecognized flags. */
	if (connection_by_uuid)
		old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection_by_uuid);
	new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection_new);
	unmanaged_changed = g_strcmp0 (old_unmanaged, new_unmanaged);

	if (connection_by_uuid)
		old_unrecognized = nm_ifcfg_connection_get_unrecognized_spec (connection_by_uuid);
	new_unrecognized = nm_ifcfg_connection_get_unrecognized_spec (connection_new);
	unrecognized_changed = g_strcmp0 (old_unrecognized, new_unrecognized);

	if (connection_by_uuid) {
		const char *old_path;

		old_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid));

		if (   !unmanaged_changed
		    && !unrecognized_changed
		    && nm_connection_compare (NM_CONNECTION (connection_by_uuid),
		                              NM_CONNECTION (connection_new),
		                              NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS |
		                              NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) {
			if (old_path && g_strcmp0 (old_path, full_path) != 0)
				_LOGI ("rename \"%s\" to "NM_IFCFG_CONNECTION_LOG_FMT" without other changes", nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid)), NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
		} else {

			/*******************************************************
			 * UPDATE
			 *******************************************************/

			if (source)
				_LOGI ("update "NM_IFCFG_CONNECTION_LOG_FMT" from %s", NM_IFCFG_CONNECTION_LOG_ARG (connection_new), NM_IFCFG_CONNECTION_LOG_PATH (old_path));
			else if (!g_strcmp0 (old_path, nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_new))))
				_LOGI ("update "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
			else if (old_path)
				_LOGI ("rename \"%s\" to "NM_IFCFG_CONNECTION_LOG_FMT, old_path, NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
			else
				_LOGI ("update and persist "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new));

			g_object_set (connection_by_uuid,
			              NM_IFCFG_CONNECTION_UNMANAGED_SPEC, new_unmanaged,
			              NM_IFCFG_CONNECTION_UNRECOGNIZED_SPEC, new_unrecognized,
			              NULL);

			if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection_by_uuid),
			                                              NM_CONNECTION (connection_new),
			                                              FALSE,  /* don't set Unsaved */
			                                              "ifcfg-update",
			                                              &local)) {
				/* Shouldn't ever get here as 'connection_new' was verified by the reader already
				 * and the UUID did not change. */
				g_assert_not_reached ();
			}
			g_assert_no_error (local);

			if (new_unmanaged || new_unrecognized) {
				if (!old_unmanaged && !old_unrecognized) {
					g_object_ref (connection_by_uuid);
					/* Unexport the connection by telling the settings service it's
					 * been removed.
					 */
					nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection_by_uuid));
					/* Remove the path so that claim_connection() doesn't complain later when
					 * interface gets managed and connection is re-added. */
					nm_connection_set_path (NM_CONNECTION (connection_by_uuid), NULL);

					/* signal_remove() will end up removing the connection from our hash,
					 * so add it back now.
					 */
					g_hash_table_insert (priv->connections,
					                     g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection_by_uuid))),
					                     connection_by_uuid);
				}
			} else {
				if (old_unmanaged /* && !new_unmanaged */) {
					_LOGI ("Managing connection "NM_IFCFG_CONNECTION_LOG_FMT" and its device because NM_CONTROLLED was true.",
					       NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
					g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_by_uuid);
				} else if (old_unrecognized /* && !new_unrecognized */) {
					_LOGI ("Managing connection "NM_IFCFG_CONNECTION_LOG_FMT" because it is now a recognized type.",
					       NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
					g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_by_uuid);
				}
			}

			if (unmanaged_changed)
				g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
			if (unrecognized_changed)
				g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNRECOGNIZED_SPECS_CHANGED);
		}
		nm_settings_connection_set_filename (NM_SETTINGS_CONNECTION (connection_by_uuid), full_path);
		g_object_unref (connection_new);
		return connection_by_uuid;
	} else {

		/*******************************************************
		 * ADD
		 *******************************************************/

		if (source)
			_LOGI ("add connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
		else
			_LOGI ("new connection "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new));
		g_hash_table_insert (priv->connections, g_strdup (uuid), connection_new);

		g_signal_connect (connection_new, NM_SETTINGS_CONNECTION_REMOVED,
		                  G_CALLBACK (connection_removed_cb),
		                  self);

		if (nm_ifcfg_connection_get_unmanaged_spec (connection_new)) {
			const char *spec;
			const char *device_id;

			spec = nm_ifcfg_connection_get_unmanaged_spec (connection_new);
			device_id = strchr (spec, ':');
			if (device_id)
				device_id++;
			else
				device_id = spec;
			_LOGW ("Ignoring connection "NM_IFCFG_CONNECTION_LOG_FMT" / device '%s' due to NM_CONTROLLED=no.",
			       NM_IFCFG_CONNECTION_LOG_ARG (connection_new), device_id);
		} else if (nm_ifcfg_connection_get_unrecognized_spec (connection_new))
			_LOGW ("Ignoring connection "NM_IFCFG_CONNECTION_LOG_FMT" of unrecognized type.", NM_IFCFG_CONNECTION_LOG_ARG (connection_new));

		/* watch changes of ifcfg hardlinks */
		g_signal_connect (G_OBJECT (connection_new), "ifcfg-changed",
		                  G_CALLBACK (connection_ifcfg_changed), self);

		if (!source) {
			/* Only raise the signal if we were called without source, i.e. if we read the connection from file.
			 * Otherwise, we were called by add_connection() which does not expect the signal. */
			if (nm_ifcfg_connection_get_unmanaged_spec (connection_new))
				g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
			else if (nm_ifcfg_connection_get_unrecognized_spec (connection_new))
				g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNRECOGNIZED_SPECS_CHANGED);
			else
				g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_new);
		}
		return connection_new;
	}
}
コード例 #7
0
static void
wireless_dialog_response_cb (GtkDialog *foo,
                             gint response,
                             gpointer user_data)
{
    NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (foo);
    WirelessDialogClosure *closure = user_data;
    NMConnection *connection, *fuzzy_match = NULL;
    NMDevice *device;
    NMAccessPoint *ap;
    GSList *all, *iter;

    if (response != GTK_RESPONSE_OK)
        goto done;

    if (!nma_wireless_dialog_get_nag_ignored (dialog)) {
        GtkWidget *nag_dialog;

        /* Nag the user about certificates or whatever.  Only destroy the dialog
         * if no nagging was done.
         */
        nag_dialog = nma_wireless_dialog_nag_user (dialog);
        if (nag_dialog) {
            gtk_window_set_transient_for (GTK_WINDOW (nag_dialog), GTK_WINDOW (dialog));
            g_signal_connect (nag_dialog, "response",
                              G_CALLBACK (nag_dialog_response_cb),
                              dialog);
            return;
        }
    }

    /* nma_wireless_dialog_get_connection() returns a connection with the
     * refcount incremented, so the caller must remember to unref it.
     */
    connection = nma_wireless_dialog_get_connection (dialog, &device, &ap);
    g_assert (connection);
    g_assert (device);

    /* Find a similar connection and use that instead */
    all = nm_remote_settings_list_connections (closure->settings);
    for (iter = all; iter; iter = g_slist_next (iter)) {
        if (nm_connection_compare (connection,
                                   NM_CONNECTION (iter->data),
                                   (NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) {
            fuzzy_match = NM_CONNECTION (iter->data);
            break;
        }
    }
    g_slist_free (all);

    if (fuzzy_match) {
        nm_client_activate_connection (closure->client,
                                       fuzzy_match,
                                       device,
                                       ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
                                       activate_existing_cb,
                                       NULL);
    } else {
        NMSetting *s_con;
        NMSettingWireless *s_wifi;
        const char *mode = NULL;

        /* Entirely new connection */

        /* Don't autoconnect adhoc networks by default for now */
        s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
        if (s_wifi)
            mode = nm_setting_wireless_get_mode (s_wifi);
        if (g_strcmp0 (mode, "adhoc") == 0) {
            s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
            if (!s_con) {
                s_con = nm_setting_connection_new ();
                nm_connection_add_setting (connection, s_con);
            }
            g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL);
        }

        nm_client_add_and_activate_connection (closure->client,
                                               connection,
                                               device,
                                               ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
                                               activate_new_cb,
                                               NULL);
    }

    /* Balance nma_wireless_dialog_get_connection() */
    g_object_unref (connection);

done:
    gtk_widget_hide (GTK_WIDGET (dialog));
    gtk_widget_destroy (GTK_WIDGET (dialog));
}
コード例 #8
0
static void
pan_connection_check_create (NMBluezDevice *self)
{
	NMConnection *connection;
	NMConnection *added;
	NMSetting *setting;
	char *uuid, *id;
	GError *error = NULL;
	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);

	g_return_if_fail (priv->capabilities & NM_BT_CAPABILITY_NAP);
	g_return_if_fail (priv->connections == NULL);
	g_return_if_fail (priv->name);

	if (priv->pan_connection || priv->pan_connection_no_autocreate) {
		/* already have a connection or we don't want to create one, nothing to do. */
		return;
	}

	/* Only try once to create a connection. If it does not succeed, we do not try again. Also,
	 * if the connection gets deleted later, do not create another one for this device. */
	priv->pan_connection_no_autocreate = TRUE;

	/* create a new connection */

	connection = nm_simple_connection_new ();

	/* Setting: Connection */
	uuid = nm_utils_uuid_generate ();
	id = g_strdup_printf (_("%s Network"), priv->name);
	setting = nm_setting_connection_new ();
	g_object_set (setting,
	              NM_SETTING_CONNECTION_ID, id,
	              NM_SETTING_CONNECTION_UUID, uuid,
	              NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_SETTING_NAME,
	              NULL);
	nm_connection_add_setting (connection, setting);

	/* Setting: Bluetooth */
	setting = nm_setting_bluetooth_new ();
	g_object_set (G_OBJECT (setting),
	              NM_SETTING_BLUETOOTH_BDADDR, priv->address,
	              NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
	              NULL);
	nm_connection_add_setting (connection, setting);

	/* Setting: IPv4 */
	setting = nm_setting_ip4_config_new ();
	g_object_set (G_OBJECT (setting),
	              NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
	              NM_SETTING_IP4_CONFIG_MAY_FAIL, FALSE,
	              NULL);
	nm_connection_add_setting (connection, setting);

	/* Setting: IPv6 */
	setting = nm_setting_ip6_config_new ();
	g_object_set (G_OBJECT (setting),
	              NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
	              NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
	              NULL);
	nm_connection_add_setting (connection, setting);

	/* Adding a new connection raises a signal which eventually calls check_emit_usable (again)
	 * which then already finds the suitable connection in priv->connections. This is confusing,
	 * so block the signal. check_emit_usable will succeed after this function call returns. */
	g_signal_handlers_block_by_func (priv->provider, cp_connection_added, self);
	added = nm_connection_provider_add_connection (priv->provider, connection, FALSE, &error);
	g_signal_handlers_unblock_by_func (priv->provider, cp_connection_added, self);

	if (added) {
		g_assert (!g_slist_find (priv->connections, added));
		g_assert (connection_compatible (self, added));
		g_assert (nm_connection_compare (added, connection, NM_SETTING_COMPARE_FLAG_EXACT));

		priv->connections = g_slist_prepend (priv->connections, g_object_ref (added));
		priv->pan_connection = added;
		priv->pan_connection_original = connection;
		nm_log_dbg (LOGD_BT, "bluez[%s] added new Bluetooth connection for NAP device: '%s' (%s)", priv->path, id, uuid);
	} else {
		nm_log_warn (LOGD_BT, "bluez[%s] couldn't add new Bluetooth connection for NAP device: '%s' (%s): %d / %s",
		             priv->path, id, uuid, error ? error->code : -1,
		             (error && error->message) ? error->message : "(unknown)");
		g_clear_error (&error);

		g_object_unref (connection);
	}

	g_free (id);
	g_free (uuid);
}
コード例 #9
0
ファイル: plugin.c プロジェクト: sujithpshankar/nm
/* update_connection:
 * @self: the plugin instance
 * @source: if %NULL, this re-reads the connection from @full_path
 *   and updates it. When passing @source, this adds a connection from
 *   memory.
 * @full_path: the filename of the keyfile to be loaded
 * @connection: an existing connection that might be updated.
 *   If given, @connection must be an existing connection that is currently
 *   owned by the plugin.
 * @protect_existing_connection: if %TRUE, and !@connection, we don't allow updating
 *   an existing connection with the same UUID.
 *   If %TRUE and @connection, allow updating only if the reload would modify
 *   @connection (without changing its UUID) or if we would create a new connection.
 *   In other words, if this paramter is %TRUE, we only allow creating a
 *   new connection (with an unseen UUID) or updating the passed in @connection
 *   (whereas the UUID cannot change).
 *   Note, that this allows for @connection to be replaced by a new connection.
 * @protected_connections: (allow-none): if given, we only update an
 *   existing connection if it is not contained in this hash.
 * @error: error in case of failure
 *
 * Loads a connection from file @full_path. This can both be used to
 * load a connection initially or to update an existing connection.
 *
 * If you pass in an existing connection and the reloaded file happens
 * to have a different UUID, the connection is deleted.
 * Beware, that means that after the function, you have a dangling pointer
 * if the returned connection is different from @connection.
 *
 * Returns: the updated connection.
 * */
static NMKeyfileConnection *
update_connection (SCPluginKeyfile *self,
                   NMConnection *source,
                   const char *full_path,
                   NMKeyfileConnection *connection,
                   gboolean protect_existing_connection,
                   GHashTable *protected_connections,
                   GError **error)
{
	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
	NMKeyfileConnection *connection_new;
	NMKeyfileConnection *connection_by_uuid;
	GError *local = NULL;
	const char *uuid;

	g_return_val_if_fail (!source || NM_IS_CONNECTION (source), NULL);
	g_return_val_if_fail (full_path || source, NULL);

	if (full_path)
		nm_log_dbg (LOGD_SETTINGS, "keyfile: loading from file \"%s\"...", full_path);

	connection_new = nm_keyfile_connection_new (source, full_path, &local);
	if (!connection_new) {
		/* Error; remove the connection */
		if (source)
			nm_log_warn (LOGD_SETTINGS, "keyfile: error creating connection %s: %s", nm_connection_get_uuid (source), local->message);
		else
			nm_log_warn (LOGD_SETTINGS, "keyfile: error loading connection from file %s: %s", full_path, local->message);
		if (   connection
		    && !protect_existing_connection
		    && (!protected_connections || !g_hash_table_contains (protected_connections, connection)))
			remove_connection (self, connection);
		g_propagate_error (error, local);
		return NULL;
	}

	uuid = nm_connection_get_uuid (NM_CONNECTION (connection_new));
	connection_by_uuid = g_hash_table_lookup (priv->connections, uuid);

	if (   connection
	    && connection != connection_by_uuid) {

		if (   (protect_existing_connection && connection_by_uuid != NULL)
		    || (protected_connections && g_hash_table_contains (protected_connections, connection))) {
			NMKeyfileConnection *conflicting = (protect_existing_connection && connection_by_uuid != NULL) ? connection_by_uuid : connection;

			if (source)
				nm_log_warn (LOGD_SETTINGS, "keyfile: cannot update protected "NM_KEYFILE_CONNECTION_LOG_FMT" connection due to conflicting UUID %s", NM_KEYFILE_CONNECTION_LOG_ARG (conflicting), uuid);
			else
				nm_log_warn (LOGD_SETTINGS, "keyfile: cannot load %s due to conflicting UUID for "NM_KEYFILE_CONNECTION_LOG_FMT, full_path, NM_KEYFILE_CONNECTION_LOG_ARG (conflicting));
			g_object_unref (connection_new);
			g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
			                      "Cannot update protected connection due to conflicting UUID");
			return NULL;
		}

		/* The new connection has a different UUID then the original one.
		 * Remove @connection. */
		remove_connection (self, connection);
	}

	if (   connection_by_uuid
	    && (   (!connection && protect_existing_connection)
	        || (protected_connections && g_hash_table_contains (protected_connections, connection_by_uuid)))) {
		if (source)
			nm_log_warn (LOGD_SETTINGS, "keyfile: cannot update connection due to conflicting UUID for "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_by_uuid));
		else
			nm_log_warn (LOGD_SETTINGS, "keyfile: cannot load %s due to conflicting UUID for "NM_KEYFILE_CONNECTION_LOG_FMT, full_path, NM_KEYFILE_CONNECTION_LOG_ARG (connection_by_uuid));
		g_object_unref (connection_new);
		g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
		                      "Skip updating protected connection during reload");
		return NULL;
	}

	if (connection_by_uuid) {
		const char *old_path;

		old_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid));

		if (nm_connection_compare (NM_CONNECTION (connection_by_uuid),
		                           NM_CONNECTION (connection_new),
		                           NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS |
		                           NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) {
			/* Nothing to do... except updating the path. */
			if (old_path && g_strcmp0 (old_path, full_path) != 0)
				nm_log_info (LOGD_SETTINGS, "keyfile: rename \"%s\" to "NM_KEYFILE_CONNECTION_LOG_FMT" without other changes", old_path, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new));
		} else {
			/* An existing connection changed. */
			if (source)
				nm_log_info (LOGD_SETTINGS, "keyfile: update "NM_KEYFILE_CONNECTION_LOG_FMT" from %s", NM_KEYFILE_CONNECTION_LOG_ARG (connection_new), NM_KEYFILE_CONNECTION_LOG_PATH (old_path));
			else if (!g_strcmp0 (old_path, nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_new))))
				nm_log_info (LOGD_SETTINGS, "keyfile: update "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new));
			else if (old_path)
				nm_log_info (LOGD_SETTINGS, "keyfile: rename \"%s\" to "NM_KEYFILE_CONNECTION_LOG_FMT, old_path, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new));
			else
				nm_log_info (LOGD_SETTINGS, "keyfile: update and persist "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new));

			if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection_by_uuid),
			                                              NM_CONNECTION (connection_new),
			                                              FALSE,  /* don't set Unsaved */
			                                              "keyfile-update",
			                                              &local)) {
				/* Shouldn't ever get here as 'connection_new' was verified by the reader already
				 * and the UUID did not change. */
				g_assert_not_reached ();
			}
			g_assert_no_error (local);
		}
		nm_settings_connection_set_filename (NM_SETTINGS_CONNECTION (connection_by_uuid), full_path);
		g_object_unref (connection_new);
		return connection_by_uuid;
	} else {
		if (source)
			nm_log_info (LOGD_SETTINGS, "keyfile: add connection "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new));
		else
			nm_log_info (LOGD_SETTINGS, "keyfile: new connection "NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection_new));
		g_hash_table_insert (priv->connections, g_strdup (uuid), connection_new);

		g_signal_connect (connection_new, NM_SETTINGS_CONNECTION_REMOVED,
		                  G_CALLBACK (connection_removed_cb),
		                  self);

		if (!source) {
			/* Only raise the signal if we were called without source, i.e. if we read the connection from file.
			 * Otherwise, we were called by add_connection() which does not expect the signal. */
			g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_new);
		}
		return connection_new;
	}
}