コード例 #1
0
static gboolean
match_parent (NMDevice *dev_parent, const char *setting_parent)
{
	g_return_val_if_fail (setting_parent, FALSE);

	if (!dev_parent)
		return FALSE;

	if (nm_utils_is_uuid (setting_parent)) {
		NMActRequest *parent_req;
		NMConnection *parent_connection;

		/* If the parent is a UUID, the connection matches if our parent
		 * device has that connection activated.
		 */
		parent_req = nm_device_get_act_request (dev_parent);
		if (!parent_req)
			return FALSE;

		parent_connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (parent_req));
		if (!parent_connection)
			return FALSE;

		if (g_strcmp0 (setting_parent, nm_connection_get_uuid (parent_connection)) != 0)
			return FALSE;
	} else {
		/* interface name */
		if (g_strcmp0 (setting_parent, nm_device_get_ip_iface (dev_parent)) != 0)
			return FALSE;
	}

	return TRUE;
}
コード例 #2
0
static GHashTable *
_create_keyring_add_attr_list (NMConnection *connection,
                               const char *setting_name,
                               const char *setting_key,
                               char **out_display_name)
{
	const char *connection_id, *connection_uuid;

	g_return_val_if_fail (connection != NULL, NULL);
	g_return_val_if_fail (setting_name != NULL, NULL);
	g_return_val_if_fail (setting_key != NULL, NULL);

	connection_uuid = nm_connection_get_uuid (connection);
	g_assert (connection_uuid);
	connection_id = nm_connection_get_id (connection);
	g_assert (connection_id);

	if (out_display_name) {
		*out_display_name = g_strdup_printf ("Network secret for %s/%s/%s",
		                                     connection_id,
		                                     setting_name,
		                                     setting_key);
	}

	return secret_attributes_build (&network_manager_secret_schema,
	                                KEYRING_UUID_TAG, connection_uuid,
	                                KEYRING_SN_TAG, setting_name,
	                                KEYRING_SK_TAG, setting_key,
	                                NULL);
}
コード例 #3
0
/* Returns an editor for @slave's master, if any */
NMConnectionEditor *
nm_connection_editor_get_master (NMConnection *slave)
{
	GHashTableIter iter;
	gpointer connection, editor;
	NMSettingConnection *s_con;
	const char *master;

	if (!active_editors)
		return NULL;

	s_con = nm_connection_get_setting_connection (slave);
	master = nm_setting_connection_get_master (s_con);
	if (!master)
		return NULL;

	g_hash_table_iter_init (&iter, active_editors);
	while (g_hash_table_iter_next (&iter, &connection, &editor)) {
		if (!g_strcmp0 (master, nm_connection_get_uuid (connection)))
			return editor;
		if (!g_strcmp0 (master, nm_connection_get_interface_name (connection)))
			return editor;
	}

	return NULL;
}
コード例 #4
0
static void
nag_dialog_response_cb (GtkDialog *nag_dialog,
                        gint response,
                        gpointer user_data)
{
	NagDialogResponseInfo *info = (NagDialogResponseInfo *) user_data;
	EAPMethod *method = (EAPMethod *) info->method;
	NMConnection *connection = (NMConnection *) info->connection;
	GtkWidget *widget;

	if (response == GTK_RESPONSE_NO) {
		/* Grab the value of the "don't bother me" checkbox */
		widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "ignore_checkbox"));
		g_assert (widget);

		method->ignore_ca_cert = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));

		/* And save it */
		_set_ignore_ca_cert (nm_connection_get_uuid (connection),
		                     method->phase2,
		                     method->ignore_ca_cert);
	}

	gtk_widget_hide (GTK_WIDGET (nag_dialog));
}
コード例 #5
0
static void
delete_slaves_of_connection (NMConnectionList *list, NMConnection *connection)
{
	const char *uuid, *iface;
	GtkTreeIter iter, types_iter;

	if (!gtk_tree_model_get_iter_first (list->model, &types_iter))
		return;

	uuid = nm_connection_get_uuid (connection);
	iface = nm_connection_get_virtual_iface_name (connection);

	do {
		if (!gtk_tree_model_iter_children (list->model, &iter, &types_iter))
			continue;

		do {
			NMRemoteConnection *candidate = NULL;
			NMSettingConnection *s_con;
			const char *master;

			gtk_tree_model_get (list->model, &iter,
			                    COL_CONNECTION, &candidate,
			                    -1);
			s_con = nm_connection_get_setting_connection (NM_CONNECTION (candidate));
			master = nm_setting_connection_get_master (s_con);
			if (master) {
				if (!g_strcmp0 (master, uuid) || !g_strcmp0 (master, iface))
					nm_remote_connection_delete (candidate, NULL, NULL);
			}

			g_object_unref (candidate);
		} while (gtk_tree_model_iter_next (list->model, &iter));
	} while (gtk_tree_model_iter_next (list->model, &types_iter));
}
コード例 #6
0
ファイル: plugin.c プロジェクト: gunchleoc/NetworkManager
static void
read_connections (SettingsPluginIbft *self)
{
	SettingsPluginIbftPrivate *priv = SETTINGS_PLUGIN_IBFT_GET_PRIVATE (self);
	GSList *blocks = NULL, *iter;
	GError *error = NULL;
	NMIbftConnection *connection;

	if (!read_ibft_blocks ("/sbin/iscsiadm", &blocks, &error)) {
		nm_log_dbg (LOGD_SETTINGS, "ibft: failed to read iscsiadm records: %s", error->message);
		g_error_free (error);
		return;
	}

	for (iter = blocks; iter; iter = iter->next) {
		connection = nm_ibft_connection_new (iter->data, &error);
		if (connection) {
			nm_log_info (LOGD_SETTINGS, "ibft: read connection '%s'",
			             nm_connection_get_id (NM_CONNECTION (connection)));
			g_hash_table_insert (priv->connections,
			                     g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))),
			                     connection);
		} else {
			nm_log_warn (LOGD_SETTINGS, "ibft: failed to read iscsiadm record: %s", error->message);
			g_clear_error (&error);
		}
	}

	g_slist_free_full (blocks, (GDestroyNotify) g_ptr_array_unref);
}
static void
remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection)
{
	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
	gboolean unmanaged, unrecognized;

	g_return_if_fail (self != NULL);
	g_return_if_fail (connection != NULL);

	_LOGI ("remove "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection));

	unmanaged = !!nm_ifcfg_connection_get_unmanaged_spec (connection);
	unrecognized = !!nm_ifcfg_connection_get_unrecognized_spec (connection);

	g_object_ref (connection);
	g_hash_table_remove (priv->connections, nm_connection_get_uuid (NM_CONNECTION (connection)));
	nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection));
	g_object_unref (connection);

	/* Emit changes _after_ removing the connection */
	if (unmanaged)
		g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
	if (unrecognized)
		g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNRECOGNIZED_SPECS_CHANGED);
}
コード例 #8
0
static gboolean
match_parent (NMDeviceVlan *self, const char *parent)
{
	NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (self);

	g_return_val_if_fail (parent != NULL, FALSE);

	if (nm_utils_is_uuid (parent)) {
		NMActRequest *parent_req;
		NMConnection *parent_connection;

		/* If the parent is a UUID, the connection matches if our parent
		 * device has that connection activated.
		 */

		parent_req = nm_device_get_act_request (priv->parent);
		if (!parent_req)
			return FALSE;

		parent_connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (parent_req));
		if (!parent_connection)
			return FALSE;

		if (g_strcmp0 (parent, nm_connection_get_uuid (parent_connection)) != 0)
			return FALSE;
	} else {
		/* interface name */
		if (g_strcmp0 (parent, nm_device_get_ip_iface (priv->parent)) != 0)
			return FALSE;
	}

	return TRUE;
}
コード例 #9
0
NMConnectionEditor *
nm_connection_editor_new (GtkWindow *parent_window,
                          NMConnection *connection,
                          NMClient *client)
{
	NMConnectionEditor *editor;
	GtkWidget *hbox;
	gboolean is_new;
	GError *error = NULL;

	g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);

	is_new = !nm_client_get_connection_by_uuid (client, nm_connection_get_uuid (connection));

	editor = g_object_new (NM_TYPE_CONNECTION_EDITOR, NULL);
	editor->parent_window = parent_window ? g_object_ref (parent_window) : NULL;
	editor->client = g_object_ref (client);
	editor->is_new_connection = is_new;

	editor->can_modify = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM);
	editor->permission_id = g_signal_connect (editor->client,
	                                          "permission-changed",
	                                          G_CALLBACK (permissions_changed_cb),
	                                          editor);

	editor->ok_button = ce_polkit_button_new (_("_Save"),
	                                          _("Save any changes made to this connection."),
	                                          _("Authenticate to save this connection for all users of this machine."),
	                                          GTK_STOCK_APPLY,
	                                          client,
	                                          NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM);
	gtk_button_set_use_underline (GTK_BUTTON (editor->ok_button), TRUE);

	g_signal_connect (editor->ok_button, "actionable",
	                  G_CALLBACK (ok_button_actionable_cb), editor);
	g_signal_connect (editor->ok_button, "authorized",
	                  G_CALLBACK (ok_button_actionable_cb), editor);
	hbox = GTK_WIDGET (gtk_builder_get_object (editor->builder, "action_area_hbox"));
	gtk_box_pack_end (GTK_BOX (hbox), editor->ok_button, TRUE, TRUE, 0);
	gtk_widget_show_all (editor->ok_button);

	if (!nm_connection_editor_set_connection (editor, connection, &error)) {
		nm_connection_editor_error (parent_window,
		                            is_new ? _("Could not create connection") : _("Could not edit connection"),
		                            "%s",
		                            error ? error->message : _("Unknown error creating connection editor dialog."));
		g_clear_error (&error);
		g_object_unref (editor);
		return NULL;
	}

	if (!active_editors)
		active_editors = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
	g_hash_table_insert (active_editors, g_object_ref (connection), editor);

	return editor;
}
コード例 #10
0
static gboolean
create_and_realize (NMDevice *device,
                    NMConnection *connection,
                    NMDevice *parent,
                    const NMPlatformLink **out_plink,
                    GError **error)
{
	const char *iface = nm_device_get_iface (device);
	NMPlatformError plerr;
	NMSettingMacvlan *s_macvlan;
	NMPlatformLnkMacvlan lnk = { };
	int parent_ifindex;

	s_macvlan = nm_connection_get_setting_macvlan (connection);
	g_assert (s_macvlan);

	if (!parent) {
		g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
		             "MACVLAN devices can not be created without a parent interface");
		return FALSE;
	}

	parent_ifindex = nm_device_get_ifindex (parent);
	g_warn_if_fail (parent_ifindex > 0);

	lnk.mode = setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan));
	if (!lnk.mode) {
		g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
		             "unsupported MACVLAN mode %u in connection %s",
		             nm_setting_macvlan_get_mode (s_macvlan),
		             nm_connection_get_uuid (connection));
		return FALSE;
	}
	lnk.no_promisc = !nm_setting_macvlan_get_promiscuous (s_macvlan);
	lnk.tap = nm_setting_macvlan_get_tap (s_macvlan);

	plerr = nm_platform_link_macvlan_add (NM_PLATFORM_GET, iface, parent_ifindex, &lnk, out_plink);
	if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
		g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
		             "Failed to create %s interface '%s' for '%s': %s",
		             lnk.tap ? "macvtap" : "macvlan",
		             iface,
		             nm_connection_get_id (connection),
		             nm_platform_error_to_string (plerr));
		return FALSE;
	}

	return TRUE;
}
コード例 #11
0
static void
populate_connection_ui (NMConnectionEditor *editor)
{
	NMSettingConnection *s_con;
	GtkWidget *name;

	name = GTK_WIDGET (gtk_builder_get_object (editor->builder, "connection_name"));

	s_con = nm_connection_get_setting_connection (editor->connection);
	gtk_entry_set_text (GTK_ENTRY (name), s_con ? nm_setting_connection_get_id (s_con) : NULL);
	gtk_widget_set_tooltip_text (name, nm_connection_get_uuid (editor->connection));

	g_signal_connect_swapped (name, "changed", G_CALLBACK (connection_editor_validate), editor);

	connection_editor_validate (editor);
}
コード例 #12
0
ファイル: common.c プロジェクト: GalliumOS/network-manager
/*
 * nmc_find_connection:
 * @connections: array of NMConnections to search in
 * @filter_type: "id", "uuid", "path" or %NULL
 * @filter_val: connection to find (connection name, UUID or path)
 * @start: where to start in @list. The location is updated so that the function
 *   can be called multiple times (for connections with the same name).
 *
 * Find a connection in @list according to @filter_val. @filter_type determines
 * what property is used for comparison. When @filter_type is NULL, compare
 * @filter_val against all types. Otherwise, only compare against the specified
 * type. If 'path' filter type is specified, comparison against numeric index
 * (in addition to the whole path) is allowed.
 *
 * Returns: found connection, or %NULL
 */
NMConnection *
nmc_find_connection (const GPtrArray *connections,
                     const char *filter_type,
                     const char *filter_val,
                     int *start)
{
	NMConnection *connection;
	NMConnection *found = NULL;
	int i;
	const char *id;
	const char *uuid;
	const char *path, *path_num;

	for (i = start ? *start : 0; i < connections->len; i++) {
		connection = NM_CONNECTION (connections->pdata[i]);

		id = nm_connection_get_id (connection);
		uuid = nm_connection_get_uuid (connection);
		path = nm_connection_get_path (connection);
		path_num = path ? strrchr (path, '/') + 1 : NULL;

		/* When filter_type is NULL, compare connection ID (filter_val)
		 * against all types. Otherwise, only compare against the specific
		 * type. If 'path' filter type is specified, comparison against
		 * numeric index (in addition to the whole path) is allowed.
		 */
		if (   (   (!filter_type || strcmp (filter_type, "id")  == 0)
		        && strcmp (filter_val, id) == 0)
		    || (   (!filter_type || strcmp (filter_type, "uuid") == 0)
		        && strcmp (filter_val, uuid) == 0)
		    || (   (!filter_type || strcmp (filter_type, "path") == 0)
		        && (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)))) {
			if (!start)
				return connection;
			if (found) {
				*start = i;
				return found;
			}
			found = connection;
		}
	}

	if (start)
		*start = 0;
	return found;
}
コード例 #13
0
/**
 * nm_remote_settings_get_connection_by_uuid:
 * @settings: the %NMRemoteSettings
 * @uuid: the UUID of the remote connection
 *
 * Returns the %NMRemoteConnection identified by @uuid.
 *
 * Returns: (transfer none): the remote connection object on success, or NULL if the object was
 *  not known
 **/
NMRemoteConnection *
nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const char *uuid)
{
	GHashTableIter iter;
	NMRemoteConnection *candidate;

	g_return_val_if_fail (settings != NULL, NULL);
	g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
	g_return_val_if_fail (uuid != NULL, NULL);

	g_hash_table_iter_init (&iter, NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->connections);
	while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) {
		if (g_strcmp0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate))) == 0)
			return candidate;
	}

	return NULL;
}
コード例 #14
0
ファイル: plugin.c プロジェクト: sujithpshankar/nm
static void
remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection)
{
	gboolean removed;

	g_return_if_fail (connection != NULL);

	nm_log_info (LOGD_SETTINGS, "keyfile: removed " NM_KEYFILE_CONNECTION_LOG_FMT, NM_KEYFILE_CONNECTION_LOG_ARG (connection));

	/* Removing from the hash table should drop the last reference */
	g_object_ref (connection);
	g_signal_handlers_disconnect_by_func (connection, connection_removed_cb, self);
	removed = g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->connections,
	                               nm_connection_get_uuid (NM_CONNECTION (connection)));
	nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection));
	g_object_unref (connection);

	g_return_if_fail (removed);
}
コード例 #15
0
static gboolean
real_connect (NMVpnServicePlugin   *plugin,
              NMConnection         *connection,
              GError              **error)
{
	NMSstpPluginPrivate *priv = NM_SSTP_PLUGIN_GET_PRIVATE (plugin);
	NMSettingVpn *s_vpn;
	const char *gwaddr;
	const char *value;

	s_vpn = nm_connection_get_setting_vpn (connection);
	g_assert (s_vpn);

	gwaddr = nm_setting_vpn_get_data_item (s_vpn, NM_SSTP_KEY_GATEWAY);
	if (!gwaddr || !strlen (gwaddr)) {
		g_set_error_literal (error,
		                     NM_VPN_PLUGIN_ERROR,
		                     NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
		                     _("Invalid or missing SSTP gateway."));
		return FALSE;
	}

	/*  Set the UUID of the connection */
	value = nm_connection_get_uuid(connection);
	if (value && strlen(value))
		nm_setting_vpn_add_data_item(s_vpn, NM_SSTP_KEY_UUID, value);

	if (!nm_sstp_properties_validate (s_vpn, error))
		return FALSE;

	if (!nm_sstp_secrets_validate (s_vpn, error))
		return FALSE;

	priv->connection = g_object_ref (connection);

	if (getenv ("NM_PPP_DUMP_CONNECTION") || debug)
		nm_connection_dump (connection);

	return nm_sstp_start_pppd_binary (NM_SSTP_PLUGIN (plugin),
	                                  s_vpn,
	                                  gwaddr,
	                                  error);
}
コード例 #16
0
void
nmt_remove_connection (NMRemoteConnection *connection)
{
	const GPtrArray *all_conns;
	GSList *slaves, *iter;
	int i;
	NMRemoteConnection *slave;
	NMSettingConnection *s_con;
	const char *uuid, *iface, *master;
	int choice;

	choice = nmt_newt_choice_dialog (_("Cancel"),
	                                 _("Delete"),
	                                 _("Are you sure you want to delete the connection '%s'?"),
	                                 nm_connection_get_id (NM_CONNECTION (connection)));
	if (choice == 1)
		return;

	g_object_ref (connection);
	remove_one_connection (connection);

	uuid = nm_connection_get_uuid (NM_CONNECTION (connection));
	iface = nm_connection_get_interface_name (NM_CONNECTION (connection));

	all_conns = nm_client_get_connections (nm_client);
	slaves = NULL;
	for (i = 0; i < all_conns->len; i++) {
		slave = all_conns->pdata[i];
		s_con = nm_connection_get_setting_connection (NM_CONNECTION (slave));
		master = nm_setting_connection_get_master (s_con);
		if (master) {
			if (!g_strcmp0 (master, uuid) || !g_strcmp0 (master, iface))
				slaves = g_slist_prepend (slaves, g_object_ref (slave));
		}
	}

	for (iter = slaves; iter; iter = iter->next)
		remove_one_connection (iter->data);
	g_slist_free_full (slaves, g_object_unref);

	g_object_unref (connection);
}
コード例 #17
0
static NMConnection *
get_connection (NMRemoteSettings *settings, const gchar *id)
{
	const gchar *uuid;
	NMConnection *connection = NULL;
	GSList *list, *l;

	list = nm_remote_settings_list_connections (settings);
	for (l = list; l; l = l->next) {
		connection = l->data;
		uuid = nm_connection_get_uuid (connection);
		if (g_strcmp0 (uuid, id) == 0) {
			g_slist_free (list);
			return connection;
		}
	}

	g_slist_free (list);
	return NULL;
}
コード例 #18
0
static void
get_property (GObject *object, guint prop_id,
			  GValue *value, GParamSpec *pspec)
{
	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
	GPtrArray *devices;

	switch (prop_id) {
	case PROP_CONNECTION:
		g_value_set_boxed (value, nm_connection_get_path (priv->connection));
		break;
	case PROP_UUID:
		g_value_set_string (value, nm_connection_get_uuid (priv->connection));
		break;
	case PROP_SPECIFIC_OBJECT:
		g_value_set_boxed (value, priv->specific_object ? priv->specific_object : "/");
		break;
	case PROP_DEVICES:
		devices = g_ptr_array_sized_new (1);
		g_ptr_array_add (devices, g_strdup (priv->device_path));
		g_value_take_boxed (value, devices);
		break;
	case PROP_STATE:
		g_value_set_uint (value, priv->state);
		break;
	case PROP_DEFAULT:
		g_value_set_boolean (value, priv->is_default);
		break;
	case PROP_DEFAULT6:
		g_value_set_boolean (value, priv->is_default6);
		break;
	case PROP_VPN:
		g_value_set_boolean (value, priv->vpn);
		break;
	case PROP_MASTER:
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
コード例 #19
0
void removeNMConnection(NMDevice *nmdevice, NMActiveConnection *conn) {
  if (conn) {
    const char *ac_uuid = nm_active_connection_get_uuid(conn);
    const GPtrArray *avail_cons = nm_device_get_available_connections(nmdevice);

    for (int i = 0; avail_cons && (i < avail_cons->len); i++) {
      NMRemoteConnection *candidate = (NMRemoteConnection *) g_ptr_array_index(avail_cons, i);
      const char *test_uuid = nm_connection_get_uuid(NM_CONNECTION(candidate));

      if (g_strcmp0(ac_uuid, test_uuid) == 0) {
        GError *err = NULL;
        nm_remote_connection_delete(candidate, NULL, &err);
        if (err) {
          DBG("WifiStatusNM: failed to remove active connection!");
          DBG("WifiStatusNM::" << __func__ << ": " << err->message);
          g_error_free(err);
        }
        break;
      }
    }
  }
}
コード例 #20
0
static gboolean
edit_connection_list_filter (NmtEditConnectionList *list,
                             NMConnection          *connection,
                             gpointer               user_data)
{
	NMSettingConnection *s_con;
	const char *master, *slave_type;
	const char *uuid, *ifname;
	const GPtrArray *conns;
	int i;
	gboolean found_master = FALSE;

	s_con = nm_connection_get_setting_connection (connection);
	g_return_val_if_fail (s_con != NULL, FALSE);

	master = nm_setting_connection_get_master (s_con);
	if (!master)
		return TRUE;
	slave_type = nm_setting_connection_get_slave_type (s_con);
	if (   g_strcmp0 (slave_type, NM_SETTING_BOND_SETTING_NAME) != 0
	    && g_strcmp0 (slave_type, NM_SETTING_TEAM_SETTING_NAME) != 0
	    && g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME) != 0)
		return TRUE;

	conns = nm_client_get_connections (nm_client);
	for (i = 0; i < conns->len; i++) {
		NMConnection *candidate = conns->pdata[i];

		uuid = nm_connection_get_uuid (candidate);
		ifname = nm_connection_get_interface_name (candidate);
		if (!g_strcmp0 (master, uuid) || !g_strcmp0 (master, ifname)) {
			found_master = TRUE;
			break;
		}
	}

	return !found_master;
}
コード例 #21
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);
	}
}
コード例 #22
0
static void
get_property (GObject *object, guint prop_id,
              GValue *value, GParamSpec *pspec)
{
	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
	GPtrArray *devices;
	NMDevice *master_device = NULL;

	switch (prop_id) {
	case PROP_CONNECTION:
		g_value_set_string (value, nm_connection_get_path (NM_CONNECTION (priv->settings_connection)));
		break;
	case PROP_ID:
		g_value_set_string (value, nm_connection_get_id (NM_CONNECTION (priv->settings_connection)));
		break;
	case PROP_UUID:
		g_value_set_string (value, nm_connection_get_uuid (NM_CONNECTION (priv->settings_connection)));
		break;
	case PROP_TYPE:
		g_value_set_string (value, nm_connection_get_connection_type (NM_CONNECTION (priv->settings_connection)));
		break;
	case PROP_SPECIFIC_OBJECT:
		g_value_set_string (value, priv->specific_object ? priv->specific_object : "/");
		break;
	case PROP_DEVICES:
		devices = g_ptr_array_sized_new (2);
		if (priv->device && priv->state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
			g_ptr_array_add (devices, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (priv->device))));
		g_ptr_array_add (devices, NULL);
		g_value_take_boxed (value, (char **) g_ptr_array_free (devices, FALSE));
		break;
	case PROP_STATE:
		if (priv->state_set)
			g_value_set_uint (value, priv->state);
		else {
			/* When the AC has just been created, its externally-visible state should
			 * be "ACTIVATING", even though internally it is "UNKNOWN".
			 */
			g_value_set_uint (value, NM_ACTIVE_CONNECTION_STATE_ACTIVATING);
		}
		break;
	case PROP_DEFAULT:
		g_value_set_boolean (value, priv->is_default);
		break;
	case PROP_IP4_CONFIG:
		/* The IP and DHCP config properties may be overridden by a subclass */
		g_value_set_string (value, "/");
		break;
	case PROP_DHCP4_CONFIG:
		g_value_set_string (value, "/");
		break;
	case PROP_DEFAULT6:
		g_value_set_boolean (value, priv->is_default6);
		break;
	case PROP_IP6_CONFIG:
		g_value_set_string (value, "/");
		break;
	case PROP_DHCP6_CONFIG:
		g_value_set_string (value, "/");
		break;
	case PROP_VPN:
		g_value_set_boolean (value, priv->vpn);
		break;
	case PROP_MASTER:
		if (priv->master)
			master_device = nm_active_connection_get_device (priv->master);
		nm_utils_g_value_set_object_path (value, master_device);
		break;
	case PROP_INT_SUBJECT:
		g_value_set_object (value, priv->subject);
		break;
	case PROP_INT_MASTER_READY:
		g_value_set_boolean (value, priv->master_ready);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
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;
	}
}
static gboolean
_internal_write_connection (NMConnection *connection,
                            const char *keyfile_dir,
                            uid_t owner_uid,
                            pid_t owner_grp,
                            const char *existing_path,
                            char **out_path,
                            GError **error)
{
	GKeyFile *key_file;
	char *data;
	gsize len;
	gboolean success = FALSE;
	char *path;
	const char *id;
	WriteInfo info = { 0 };
	GError *local_err = NULL;

	g_return_val_if_fail (!out_path || !*out_path, FALSE);
	g_return_val_if_fail (keyfile_dir && keyfile_dir[0] == '/', FALSE);

	if (!nm_connection_verify (connection, error))
		g_return_val_if_reached (FALSE);

	id = nm_connection_get_id (connection);
	g_assert (id && *id);

	info.keyfile_dir = keyfile_dir;

	key_file = nm_keyfile_write (connection, _handler_write, &info, error);
	if (!key_file)
		return FALSE;
	data = g_key_file_to_data (key_file, &len, error);
	g_key_file_unref (key_file);
	if (!data)
		return FALSE;

	/* If we have existing file path, use it. Else generate one from
	 * connection's ID.
	 */
	if (existing_path != NULL) {
		path = g_strdup (existing_path);
	} else {
		char *filename_escaped = nm_keyfile_plugin_utils_escape_filename (id);

		path = g_build_filename (keyfile_dir, filename_escaped, NULL);
		g_free (filename_escaped);
	}

	/* If a file with this path already exists (but isn't the existing path
	 * of the connection) then we need another name.  Multiple connections
	 * can have the same ID (ie if two connections with the same ID are visible
	 * to different users) but of course can't have the same path.  Yeah,
	 * there's a race here, but there's not a lot we can do about it, and
	 * we shouldn't get more than one connection with the same UUID either.
	 */
	if (g_strcmp0 (path, existing_path) != 0 && g_file_test (path, G_FILE_TEST_EXISTS)) {
		guint i;
		gboolean name_found = FALSE;

		/* A keyfile with this connection's ID already exists. Pick another name. */
		for (i = 0; i < 100; i++) {
			char *filename, *filename_escaped;

			if (i == 0)
				filename = g_strdup_printf ("%s-%s", id, nm_connection_get_uuid (connection));
			else
				filename = g_strdup_printf ("%s-%s-%u", id, nm_connection_get_uuid (connection), i);

			filename_escaped = nm_keyfile_plugin_utils_escape_filename (filename);

			g_free (path);
			path = g_strdup_printf ("%s/%s", keyfile_dir, filename_escaped);
			g_free (filename);
			g_free (filename_escaped);
			if (g_strcmp0 (path, existing_path) == 0 || !g_file_test (path, G_FILE_TEST_EXISTS)) {
				name_found = TRUE;
				break;
			}
		}
		if (!name_found) {
			if (existing_path == NULL) {
				/* this really should not happen, we tried hard to find an unused name... bail out. */
				g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
				                    "could not find suitable keyfile file name (%s already used)", path);
				g_free (path);
				goto out;
			}
			/* Both our preferred path based on connection id and id-uuid are taken.
			 * Fallback to @existing_path */
			g_free (path);
			path = g_strdup (existing_path);
		}
	}

	/* In case of updating the connection and changing the file path,
	 * we need to remove the old one, not to end up with two connections.
	 */
	if (existing_path != NULL && strcmp (path, existing_path) != 0)
		unlink (existing_path);

	g_file_set_contents (path, data, len, &local_err);
	if (local_err) {
		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
		             "%s.%d: error writing to file '%s': %s", __FILE__, __LINE__,
		             path, local_err->message);
		g_error_free (local_err);
		g_free (path);
		goto out;
	}

	if (chown (path, owner_uid, owner_grp) < 0) {
		g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
		             "%s.%d: error chowning '%s': %d", __FILE__, __LINE__,
		             path, errno);
		unlink (path);
	} else {
		if (chmod (path, S_IRUSR | S_IWUSR) < 0) {
			g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
			             "%s.%d: error setting permissions on '%s': %d", __FILE__,
			             __LINE__, path, errno);
			unlink (path);
		} else {
			if (out_path && g_strcmp0 (existing_path, path)) {
				*out_path = path;  /* pass path out to caller */
				path = NULL;
			}
			success = TRUE;
		}
	}
	g_free (path);

out:
	g_free (data);
	return success;
}
static void
connection_removed_cb (NMSettingsConnection *obj, gpointer user_data)
{
	g_hash_table_remove (SC_PLUGIN_IFCFG_GET_PRIVATE (user_data)->connections,
	                     nm_connection_get_uuid (NM_CONNECTION (obj)));
}
static void
cert_writer (NMConnection *connection,
             GKeyFile *file,
             NMKeyfileWriteTypeDataCert *cert_data,
             WriteInfo *info,
             GError **error)
{
	const char *setting_name = nm_setting_get_name (NM_SETTING (cert_data->setting));
	NMSetting8021xCKScheme scheme;
	NMSetting8021xCKFormat format;
	const char *path = NULL, *ext = "pem";

	scheme = cert_data->scheme_func (cert_data->setting);
	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
		char *tmp = NULL;
		const char *accepted_path = NULL;

		path = cert_data->path_func (cert_data->setting);
		g_assert (path);

		if (g_str_has_prefix (path, info->keyfile_dir)) {
			const char *p = path + strlen (info->keyfile_dir);

			/* If the path is rooted in the keyfile directory, just use a
			 * relative path instead of an absolute one.
			 */
			if (*p == '/') {
				while (*p == '/')
					p++;
				if (p[0]) {
					/* If @p looks like an integer list, the following detection will fail too and
					 * we will file:// qualify the path below. We thus avoid writing a path string
					 * that would be interpreted as legacy binary format by reader. */
					tmp = nm_keyfile_detect_unqualified_path_scheme (info->keyfile_dir, p, -1, FALSE, NULL);
					if (tmp) {
						g_clear_pointer (&tmp, g_free);
						accepted_path = p;
					}
				}
			}
		}
		if (!accepted_path) {
			/* What we are about to write, must also be understood by the reader.
			 * Otherwise, add a file:// prefix */
			tmp = nm_keyfile_detect_unqualified_path_scheme (info->keyfile_dir, path, -1, FALSE, NULL);
			if (tmp) {
				g_clear_pointer (&tmp, g_free);
				accepted_path = path;
			}
		}

		if (!accepted_path)
			accepted_path = tmp = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL);
		nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->property_name, accepted_path);
		g_free (tmp);
	} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
		GBytes *blob;
		const guint8 *blob_data;
		gsize blob_len;
		gboolean success;
		GError *local = NULL;
		char *new_path;

		blob = cert_data->blob_func (cert_data->setting);
		g_assert (blob);
		blob_data = g_bytes_get_data (blob, &blob_len);

		if (cert_data->format_func) {
			/* Get the extension for a private key */
			format = cert_data->format_func (cert_data->setting);
			if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
				ext = "p12";
		} else {
			/* DER or PEM format certificate? */
			if (blob_len > 2 && blob_data[0] == 0x30 && blob_data[1] == 0x82)
				ext = "der";
		}

		/* Write the raw data out to the standard file so that we can use paths
		 * from now on instead of pushing around the certificate data.
		 */
		new_path = g_strdup_printf ("%s/%s-%s.%s", info->keyfile_dir, nm_connection_get_uuid (connection),
		                            cert_data->suffix, ext);

		success = write_cert_key_file (new_path, blob_data, blob_len, &local);
		if (success) {
			/* Write the path value to the keyfile.
			 * We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64,"  */
			nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->property_name, strrchr (new_path, '/') + 1);
		} else {
			nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: failed to write certificate to file %s: %s",
			             setting_name, cert_data->property_name, new_path, local->message);
			g_error_free (local);
		}
		g_free (new_path);
	} else {
		/* scheme_func() returns UNKNOWN in all other cases. The only valid case
		 * where a scheme is allowed to be UNKNOWN, is unsetting the value. In this
		 * case, we don't expect the writer to be called, because the default value
		 * will not be serialized.
		 * The only other reason for the scheme to be UNKNOWN is an invalid cert.
		 * But our connection verifies, so that cannot happen either. */
		g_return_if_reached ();
	}
}
コード例 #27
0
static void
add_row (NetDeviceEthernet *device, NMConnection *connection)
{
        GtkWidget *row;
        GtkWidget *widget;
        GtkWidget *box;
        GtkWidget *details;
        NMDevice *nmdev;
        NMActiveConnection *aconn;
        gboolean active;
        GtkWidget *image;

        active = FALSE;

        nmdev = net_device_get_nm_device (NET_DEVICE (device));
        aconn = nm_device_get_active_connection (nmdev);
        if (aconn) {
                const gchar *uuid1, *uuid2;
                uuid1 = nm_active_connection_get_uuid (aconn);
                uuid2 = nm_connection_get_uuid (connection);
                active = g_strcmp0 (uuid1, uuid2) == 0;
        }

        row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
        gtk_box_pack_start (GTK_BOX (row), box, FALSE, TRUE, 0);
        widget = gtk_label_new (nm_connection_get_id (connection));
        gtk_widget_set_margin_start (widget, 12);
        gtk_widget_set_margin_end (widget, 12);
        gtk_widget_set_margin_top (widget, 12);
        gtk_widget_set_margin_bottom (widget, 12);
        gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);

        if (active) {
                widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU);
                gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
                gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
                gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);

                details = gtk_grid_new ();
                gtk_grid_set_row_spacing (GTK_GRID (details), 10);
                gtk_grid_set_column_spacing (GTK_GRID (details), 10);

                gtk_box_pack_start (GTK_BOX (row), details, FALSE, TRUE, 0);

                add_details (details, nmdev, connection);
        }

        /* filler */
        widget = gtk_label_new ("");
        gtk_widget_set_hexpand (widget, TRUE);
        gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);

        image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU);
        gtk_widget_show (image);
        widget = gtk_button_new ();
        gtk_style_context_add_class (gtk_widget_get_style_context (widget), "image-button");
        gtk_widget_set_margin_start (widget, 12);
        gtk_widget_set_margin_end (widget, 12);
        gtk_widget_set_margin_top (widget, 12);
        gtk_widget_set_margin_bottom (widget, 12);
        gtk_widget_show (widget);
        gtk_container_add (GTK_CONTAINER (widget), image);
        gtk_widget_set_halign (widget, GTK_ALIGN_CENTER);
        gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
        atk_object_set_name (gtk_widget_get_accessible (widget), _("Options…"));
        gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0);
        g_object_set_data (G_OBJECT (row), "edit", widget);
        g_object_set_data (G_OBJECT (widget), "row", row);
        g_signal_connect (widget, "clicked",
                          G_CALLBACK (show_details_for_row), device);

        gtk_widget_show_all (row);

        g_object_set_data (G_OBJECT (row), "connection", connection);

        gtk_container_add (GTK_CONTAINER (device->list), row);
}
コード例 #28
0
static void
ui_to_setting (CEPageVlan *self)
{
    CEPageVlanPrivate *priv = CE_PAGE_VLAN_GET_PRIVATE (self);
    NMConnection *connection = CE_PAGE (self)->connection;
    NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
    GByteArray *cloned_mac = NULL;
    VlanParent *parent = NULL;
    int parent_id, vid;
    const char *parent_iface = NULL, *parent_uuid = NULL;
    const char *slave_type;
    const char *iface;
    char *tmp_parent_iface = NULL;
    GType hwtype;
    gboolean mtu_set;
    int mtu;

    parent_id = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->parent));
    if (parent_id == -1) {
        parent_iface = gtk_entry_get_text (priv->parent_entry);
        tmp_parent_iface = g_strndup (parent_iface, strcspn (parent_iface, " "));
        parent_iface = tmp_parent_iface;
    } else {
        parent = priv->parents[parent_id];
        if (parent->connection)
            parent_uuid = nm_connection_get_uuid (parent->connection);
        if (parent->device)
            parent_iface = nm_device_get_iface (parent->device);
    }

    g_assert (parent_uuid != NULL || parent_iface != NULL);

    slave_type = nm_setting_connection_get_slave_type (s_con);
    if (parent_uuid) {
        /* Update NMSettingConnection:master if it's set, but don't
         * set it if it's not.
         */
        if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME)) {
            g_object_set (s_con,
                          NM_SETTING_CONNECTION_MASTER, parent_uuid,
                          NULL);
        }
    } else if (!g_strcmp0 (slave_type, NM_SETTING_VLAN_SETTING_NAME)) {
        g_object_set (s_con,
                      NM_SETTING_CONNECTION_MASTER, NULL,
                      NM_SETTING_CONNECTION_SLAVE_TYPE, NULL,
                      NULL);
    }

    if (parent && NM_IS_DEVICE_ETHERNET (parent->device))
        hwtype = NM_TYPE_SETTING_WIRED;
    else
        hwtype = G_TYPE_NONE;

    if (priv->s_hw && G_OBJECT_TYPE (priv->s_hw) != hwtype) {
        nm_connection_remove_setting (connection, G_OBJECT_TYPE (priv->s_hw));
        priv->s_hw = NULL;
    }

    iface = gtk_entry_get_text (priv->name_entry);
    vid = gtk_spin_button_get_value_as_int (priv->id_entry);

    g_object_set (priv->setting,
                  NM_SETTING_VLAN_PARENT, parent_uuid ? parent_uuid : parent_iface,
                  NM_SETTING_VLAN_INTERFACE_NAME, iface,
                  NM_SETTING_VLAN_ID, vid,
                  NULL);

    if (hwtype != G_TYPE_NONE) {
        cloned_mac = ce_page_entry_to_mac (priv->cloned_mac, ARPHRD_ETHER, NULL);
        mtu_set = g_ascii_isdigit (*gtk_entry_get_text (GTK_ENTRY (priv->mtu)));
        mtu = gtk_spin_button_get_value_as_int (priv->mtu);

        if (cloned_mac || mtu_set) {
            if (!priv->s_hw) {
                priv->s_hw = g_object_new (hwtype, NULL);
                nm_connection_add_setting (connection, priv->s_hw);
            }

            g_object_set (priv->s_hw,
                          NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac,
                          NM_SETTING_WIRED_MTU, (guint32) mtu,
                          NULL);

            if (cloned_mac)
                g_byte_array_free (cloned_mac, TRUE);
        } else if (priv->s_hw) {
            nm_connection_remove_setting (connection, G_OBJECT_TYPE (priv->s_hw));
            priv->s_hw = NULL;
        }
    }

    g_free (tmp_parent_iface);
}
コード例 #29
0
ファイル: applet-agent.c プロジェクト: domsom/nm-applet-ds
static void
get_secrets (NMSecretAgent *agent,
             NMConnection *connection,
             const char *connection_path,
             const char *setting_name,
             const char **hints,
             guint32 flags,
             NMSecretAgentGetSecretsFunc callback,
             gpointer callback_data)
{
	AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent);
	Request *r;
	GError *error = NULL;
	NMSettingConnection *s_con;
	NMSetting *setting;
	const char *uuid, *ctype;
	KeyringCall *call;

	setting = nm_connection_get_setting_by_name (connection, setting_name);
	if (!setting) {
		error = g_error_new (NM_SECRET_AGENT_ERROR,
		                     NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
		                     "%s.%d - Connection didn't have requested setting '%s'.",
		                     __FILE__, __LINE__, setting_name);
		callback (agent, connection, NULL, error, callback_data);
		g_error_free (error);
		return;
	}

	uuid = nm_connection_get_uuid (connection);

	s_con = nm_connection_get_setting_connection (connection);
	g_assert (s_con);
	ctype = nm_setting_connection_get_connection_type (s_con);

	if (!uuid || !ctype) {
		error = g_error_new (NM_SECRET_AGENT_ERROR,
		                     NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
		                     "%s.%d - Connection didn't have required UUID.",
		                     __FILE__, __LINE__);
		callback (agent, connection, NULL, error, callback_data);
		g_error_free (error);
		return;
	}

	/* Track the secrets request */
	r = request_new (agent, connection, connection_path, setting_name, hints, flags, callback, NULL, NULL, callback_data);
	g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r);

	/* VPN passwords are handled by the VPN plugin's auth dialog */
	if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME)) {
		ask_for_secrets (r);
		return;
	}

	/* For everything else we scrape the keyring for secrets first, and ask
	 * later if required.
	 */
	call = keyring_call_new (r);
	call->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET,
	                                              keyring_find_secrets_cb,
	                                              call,
	                                              keyring_call_free,
	                                              KEYRING_UUID_TAG,
	                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
	                                              uuid,
	                                              KEYRING_SN_TAG,
	                                              GNOME_KEYRING_ATTRIBUTE_TYPE_STRING,
	                                              setting_name,
	                                              NULL);
	r->keyring_calls = g_slist_append (r->keyring_calls, call);
}
コード例 #30
0
static void
get_secrets (NMSecretAgent *agent,
             NMConnection *connection,
             const char *connection_path,
             const char *setting_name,
             const char **hints,
             guint32 flags,
             NMSecretAgentGetSecretsFunc callback,
             gpointer callback_data)
{
	AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent);
	Request *r;
	GError *error = NULL;
	NMSettingConnection *s_con;
	NMSetting *setting;
	const char *uuid, *ctype;
	GHashTable *attrs;

	setting = nm_connection_get_setting_by_name (connection, setting_name);
	if (!setting) {
		error = g_error_new (NM_SECRET_AGENT_ERROR,
		                     NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
		                     "%s.%d - Connection didn't have requested setting '%s'.",
		                     __FILE__, __LINE__, setting_name);
		callback (agent, connection, NULL, error, callback_data);
		g_error_free (error);
		return;
	}

	uuid = nm_connection_get_uuid (connection);

	s_con = nm_connection_get_setting_connection (connection);
	g_assert (s_con);
	ctype = nm_setting_connection_get_connection_type (s_con);

	if (!uuid || !ctype) {
		error = g_error_new (NM_SECRET_AGENT_ERROR,
		                     NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
		                     "%s.%d - Connection didn't have required UUID.",
		                     __FILE__, __LINE__);
		callback (agent, connection, NULL, error, callback_data);
		g_error_free (error);
		return;
	}

	/* Track the secrets request */
	r = request_new (agent, connection, connection_path, setting_name, hints, flags, callback, NULL, NULL, callback_data);
	g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r);

	/* VPN passwords are handled by the VPN plugin's auth dialog */
	if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME)) {
		ask_for_secrets (r);
		return;
	}

	/* Only handle non-VPN secrets if we're supposed to */
	if (priv->vpn_only == TRUE) {
		error = g_error_new_literal (NM_SECRET_AGENT_ERROR,
		                             NM_SECRET_AGENT_ERROR_NO_SECRETS,
		                             "Only handling VPN secrets at this time.");
		callback (agent, connection, NULL, error, callback_data);
		g_error_free (error);
		return;
	}

	/* For everything else we scrape the keyring for secrets first, and ask
	 * later if required.
	 */
	attrs = secret_attributes_build (&network_manager_secret_schema,
	                                 KEYRING_UUID_TAG, uuid,
	                                 KEYRING_SN_TAG, setting_name,
	                                 NULL);

	secret_service_search (NULL, &network_manager_secret_schema, attrs,
	                       SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
	                       r->cancellable, keyring_find_secrets_cb, r);

	r->keyring_calls++;
	g_hash_table_unref (attrs);
}