static gboolean
check_connection_interface_name (NMConnection *orig,
                                 NMConnection *candidate,
                                 GHashTable *settings)
{
	GHashTable *props;
	const char *orig_ifname, *cand_ifname;
	NMSettingConnection *s_con_orig, *s_con_cand;

	props = check_property_in_hash (settings,
	                                NM_SETTING_CONNECTION_SETTING_NAME,
	                                NM_SETTING_CONNECTION_INTERFACE_NAME);
	if (!props)
		return TRUE;

	/* If one of the interface names is NULL, we accept that connection */
	s_con_orig = nm_connection_get_setting_connection (orig);
	s_con_cand = nm_connection_get_setting_connection (candidate);
	orig_ifname = nm_setting_connection_get_interface_name (s_con_orig);
	cand_ifname = nm_setting_connection_get_interface_name (s_con_cand);

	if (!orig_ifname || !cand_ifname) {
		remove_from_hash (settings, props,
		                  NM_SETTING_CONNECTION_SETTING_NAME,
		                  NM_SETTING_CONNECTION_INTERFACE_NAME);
		return TRUE;
	}
	return FALSE;
}
Example #2
0
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
    NMSettingConnection *s_con;
    const char *ctype, *iface_name;

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

    ctype = nm_setting_connection_get_connection_type (s_con);
    if (strcmp (ctype, NM_SETTING_GENERIC_SETTING_NAME) != 0) {
        g_set_error (error, NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_NOT_GENERIC_CONNECTION,
                     "The connection was not a generic connection.");
        return FALSE;
    }

    iface_name = nm_setting_connection_get_interface_name (s_con);
    if (!iface_name) {
        g_set_error (error, NM_DEVICE_GENERIC_ERROR, NM_DEVICE_GENERIC_ERROR_MISSING_INTERFACE_NAME,
                     "The connection did not specify an interface name.");
        return FALSE;
    }

    return NM_DEVICE_CLASS (nm_device_generic_parent_class)->connection_compatible (device, connection, error);
}
/* Print details of connection */
static void
show_connection (NMConnection *connection)
{
	NMSettingConnection *s_con;
	guint64 timestamp;
	char *timestamp_str;
	char timestamp_real_str[64];
	const char *val1, *val2, *val3, *val3a, *val4, *val5;

	s_con = nm_connection_get_setting_connection (connection);
	if (s_con) {
		/* Get various info from NMSettingConnection and show it */
		timestamp = nm_setting_connection_get_timestamp (s_con);
		timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
		strftime (timestamp_real_str, sizeof (timestamp_real_str), "%c", localtime ((time_t *) &timestamp));

		val1 = nm_setting_connection_get_id (s_con);
		val2 = nm_setting_connection_get_uuid (s_con);
		val3 = nm_setting_connection_get_connection_type (s_con);
		val3a = nm_setting_connection_get_interface_name (s_con);
		val4 = nm_connection_get_path (connection);
		val5 = timestamp ? timestamp_real_str : "never";

		printf ("%-25s | %s | %-15s | %10s | %-43s | %s\n", val1, val2, val3, val3a, val4, val5);

		g_free (timestamp_str);
	}
}
void
nm_utils_complete_generic (NMPlatform *platform,
                           NMConnection *connection,
                           const char *ctype,
                           const GSList *existing,
                           const char *preferred_id,
                           const char *fallback_id_prefix,
                           const char *ifname_prefix,
                           gboolean default_enable_ipv6)
{
	NMSettingConnection *s_con;
	char *id, *uuid, *ifname;
	GHashTable *parameters;

	g_assert (fallback_id_prefix);

	s_con = nm_connection_get_setting_connection (connection);
	if (!s_con) {
		s_con = (NMSettingConnection *) nm_setting_connection_new ();
		nm_connection_add_setting (connection, NM_SETTING (s_con));
	}
	g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL);

	if (!nm_setting_connection_get_uuid (s_con)) {
		uuid = nm_utils_uuid_generate ();
		g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_UUID, uuid, NULL);
		g_free (uuid);
	}

	/* Add a connection ID if absent */
	if (!nm_setting_connection_get_id (s_con)) {
		id = get_new_connection_name (existing, preferred_id, fallback_id_prefix);
		g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL);
		g_free (id);
	}

	/* Add an interface name, if requested */
	if (ifname_prefix && !nm_setting_connection_get_interface_name (s_con)) {
		ifname = get_new_connection_ifname (platform, existing, ifname_prefix);
		g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NULL);
		g_free (ifname);
	}

	/* Normalize */
	parameters = g_hash_table_new (g_str_hash, g_str_equal);
	g_hash_table_insert (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD,
	                     default_enable_ipv6 ? NM_SETTING_IP6_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_IGNORE);
	nm_connection_normalize (connection, parameters, NULL, NULL);
	g_hash_table_destroy (parameters);
}
static void
vlan_settings_changed (GObject    *object,
                       GParamSpec *pspec,
                       gpointer    user_data)
{
	NMEditorVlanWidgetBinding *binding = user_data;
	const char *ifname, *parent;
	char *ifname_parent;
	int ifname_id, id;

	if (binding->updating)
		return;

	ifname = nm_setting_connection_get_interface_name (binding->s_con);
	parent = nm_setting_vlan_get_parent (binding->s_vlan);
	id = nm_setting_vlan_get_id (binding->s_vlan);

	if (!parse_interface_name (ifname, &ifname_parent, &ifname_id))
		return;

	/* If the id in INTERFACE_NAME changed, and ID is either unset, or was previously
	 * in sync with INTERFACE_NAME, then update ID.
	 */
	if (   id != ifname_id
	    && (id == binding->last_ifname_id || id == 0)) {
		binding->updating = TRUE;
		g_object_set (G_OBJECT (binding->s_vlan),
		              NM_SETTING_VLAN_ID, ifname_id,
		              NULL);
		binding->updating = FALSE;
	}

	/* If the PARENT in INTERFACE_NAME changed, and PARENT is either unset, or was
	 * previously in sync with INTERFACE_NAME, then update PARENT.
	 */
	if (   g_strcmp0 (parent, ifname_parent) != 0
	    && (   g_strcmp0 (parent, binding->last_ifname_parent) == 0
	        || !parent || !*parent)) {
		binding->updating = TRUE;
		g_object_set (G_OBJECT (binding->s_vlan),
		              NM_SETTING_VLAN_PARENT, ifname_parent,
		              NULL);
		binding->updating = FALSE;
	}

	g_free (binding->last_ifname_parent);
	binding->last_ifname_parent = ifname_parent;
	binding->last_ifname_id = ifname_id;
}
static gboolean
check_connection_compatible (NMDevice *device, NMConnection *connection)
{
	NMSettingConnection *s_con;

	if (!NM_DEVICE_CLASS (nm_device_generic_parent_class)->check_connection_compatible (device, connection))
		return FALSE;

	if (!nm_connection_is_type (connection, NM_SETTING_GENERIC_SETTING_NAME))
		return FALSE;

	s_con = nm_connection_get_setting_connection (connection);
	if (!nm_setting_connection_get_interface_name (s_con))
		return FALSE;

	return TRUE;
}
/**
 * nm_editor_bind_vlan_name:
 * @s_vlan: an #NMSettingVlan
 *
 * Binds together several properties on @s_vlan, so that if the
 * %NM_SETTING_VLAN_INTERFACE_NAME matches %NM_SETTING_VLAN_PARENT
 * and %NM_SETTING_VLAN_ID in the obvious way, then changes to
 * %NM_SETTING_VLAN_INTERFACE_NAME will propagate to the other
 * two properties automatically.
 */
void
nm_editor_bind_vlan_name (NMSettingVlan *s_vlan,
                          NMSettingConnection *s_con)
{
	NMEditorVlanWidgetBinding *binding;
	const char *ifname;

	binding = g_slice_new0 (NMEditorVlanWidgetBinding);
	binding->s_vlan = s_vlan;
	binding->s_con = s_con;

	g_signal_connect (s_con, "notify::" NM_SETTING_CONNECTION_INTERFACE_NAME,
	                  G_CALLBACK (vlan_settings_changed), binding);

	g_object_weak_ref (G_OBJECT (s_vlan), vlan_target_destroyed, binding);

	ifname = nm_setting_connection_get_interface_name (s_con);
	if (!parse_interface_name (ifname, &binding->last_ifname_parent, &binding->last_ifname_id)) {
		binding->last_ifname_parent = NULL;
		binding->last_ifname_id = 0;
	}
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingConnection *s_con;
	NMSettingInfinibandPrivate *priv = NM_SETTING_INFINIBAND_GET_PRIVATE (setting);
	guint32 normerr_max_mtu = 0;

	if (priv->mac_address && !nm_utils_hwaddr_valid (priv->mac_address, INFINIBAND_ALEN)) {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS);
		return FALSE;
	}

	if (!g_strcmp0 (priv->transport_mode, "datagram")) {
		if (priv->mtu > 2044)
			normerr_max_mtu = 2044;
	} else if (!g_strcmp0 (priv->transport_mode, "connected")) {
		if (priv->mtu > 65520)
			normerr_max_mtu = 65520;
	} else {
		g_set_error_literal (error,
		                     NM_CONNECTION_ERROR,
		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
		                     _("property is invalid"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_TRANSPORT_MODE);
		return FALSE;
	}

	if (priv->parent) {
		if (!nm_utils_iface_valid_name (priv->parent)) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
			                     _("not a valid interface name"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
			return FALSE;
		}
		if (priv->p_key == -1) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
			                     _("Must specify a P_Key if specifying parent"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
		}
	}

	if (priv->p_key != -1) {
		if (!priv->mac_address && !priv->parent) {
			g_set_error_literal (error,
			                     NM_CONNECTION_ERROR,
			                     NM_CONNECTION_ERROR_MISSING_PROPERTY,
			                     _("InfiniBand P_Key connection did not specify parent interface name"));
			g_prefix_error (error, "%s: ", NM_SETTING_INFINIBAND_PARENT);
			return FALSE;
		}
	}

	s_con = nm_connection_get_setting_connection (connection);
	if (s_con) {
		const char *interface_name = nm_setting_connection_get_interface_name (s_con);

		if (!interface_name)
			;
		else if (!nm_utils_iface_valid_name (interface_name)) {
			/* report the error for NMSettingConnection:interface-name, because
			 * it's that property that is invalid -- although we currently verify()
			 * NMSettingInfiniband.
			 **/
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("'%s' is not a valid interface name"),
			             interface_name);
			g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME);
			return FALSE;
		} else {
			if (priv->p_key != -1) {
				if (!priv->virtual_iface_name)
					priv->virtual_iface_name = g_strdup_printf ("%s.%04x", priv->parent, priv->p_key);

				if (strcmp (interface_name, priv->virtual_iface_name) != 0) {
					/* We don't support renaming software infiniband devices. Later we might, but
					 * for now just reject such connections.
					 **/
					g_set_error (error,
					             NM_CONNECTION_ERROR,
					             NM_CONNECTION_ERROR_INVALID_PROPERTY,
					             _("interface name of software infiniband device must be '%s' or unset (instead it is '%s')"),
					             priv->virtual_iface_name, interface_name);
					g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME);
					return FALSE;
				}
			}
		}
	}

	/* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */

	if (normerr_max_mtu > 0) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("mtu for transport mode '%s' can be at most %d but it is %d"),
		             priv->transport_mode, normerr_max_mtu, priv->mtu);
		g_prefix_error (error, "%s.%s: ", NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MTU);
		return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
	}

	return TRUE;
}
static gboolean
init_plugin_ui (VpncEditor *self,
                NMConnection *connection,
                gboolean new_connection,
                GError **error)
{
	VpncEditorPrivate *priv = VPNC_EDITOR_GET_PRIVATE (self);
	NMSettingConnection *s_con = NULL;
	NMSettingVpn *s_vpn = NULL;
	GtkWidget *widget;
	GtkListStore *store;
	GtkTreeIter iter;
	const char *value = NULL;
	int active = -1;
	const char *natt_mode = NULL;
	const char *ike_dh_group = NULL;
	const char *vendor = NULL;
	const char *pfs_group = NULL;
	gboolean enabled = FALSE;
	GtkFileFilter *filter;

	if (connection) {
		s_con = nm_connection_get_setting_connection (connection);
		s_vpn = nm_connection_get_setting_vpn (connection);
	}

	priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "gateway_entry"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_GATEWAY);
		if (value && strlen (value))
			gtk_entry_set_text (GTK_ENTRY (widget), value);
	}
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "group_entry"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_ID);
		if (value && strlen (value))
			gtk_entry_set_text (GTK_ENTRY (widget), value);
	}
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "encryption_combo"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));

	store = gtk_list_store_new (1, G_TYPE_STRING);

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("Secure (default)"), -1);

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("Weak (use with caution)"), -1);
	if (s_vpn && (active < 0)) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_SINGLE_DES);
		if (value && !strcmp (value, "yes"))
			active = 1;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("None (completely insecure)"), -1);
	if (s_vpn && (active < 0)) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_NO_ENCRYPTION);
		if (value && !strcmp (value, "yes"))
			active = 2;
	}

	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
	g_object_unref (store);
	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 0 : active);
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	/* Fill the VPN passwords *before* initializing the PW type combos, since
	 * knowing if there are passwords when initializing the combos is helpful.
	 */
	setup_password_widget (self,
	                       "user_password_entry",
	                       s_vpn,
	                       NM_VPNC_KEY_XAUTH_PASSWORD,
	                       new_connection);
	setup_password_widget (self,
	                       "group_password_entry",
	                       s_vpn,
	                       NM_VPNC_KEY_SECRET,
	                       new_connection);

	init_password_icon (self,
	                    s_vpn,
	                    NM_VPNC_KEY_XAUTH_PASSWORD,
	                    NM_VPNC_KEY_XAUTH_PASSWORD_TYPE,
	                    "user_password_entry");
	init_password_icon (self,
	                    s_vpn,
	                    NM_VPNC_KEY_SECRET,
	                    NM_VPNC_KEY_SECRET_TYPE,
	                    "group_password_entry");

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user_entry"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_XAUTH_USER);
		if (value && strlen (value))
			gtk_entry_set_text (GTK_ENTRY (widget), value);
	}
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "domain_entry"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_DOMAIN);
		if (value && strlen (value))
			gtk_entry_set_text (GTK_ENTRY (widget), value);
	}
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	/* Vendor combo */
	active = -1;
	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
	if (s_vpn)
		vendor = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_VENDOR);

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("Cisco (default)"), 1, NM_VPNC_VENDOR_CISCO, -1);
	if ((active < 0) && vendor) {
		if (!strcmp (vendor, NM_VPNC_VENDOR_CISCO))
			active = 0;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("Netscreen"), 1, NM_VPNC_VENDOR_NETSCREEN, -1);
	if ((active < 0) && vendor) {
		if (!strcmp (vendor, NM_VPNC_VENDOR_NETSCREEN))
			active = 1;
	}

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "vendor_combo"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
	g_object_unref (store);
	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 0 : active);
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	/* Application version */
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "application_version_entry"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_APP_VERSION);
		if (value && strlen (value))
			gtk_entry_set_text (GTK_ENTRY (widget), value);
	}
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	/* Interface name */
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "interface_name_entry"));
	g_return_val_if_fail (widget != NULL, FALSE);
	if (s_con) {
		value = nm_setting_connection_get_interface_name (s_con);
		if (value && strlen (value))
			gtk_entry_set_text (GTK_ENTRY (widget), value);
	}
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	active = -1;
	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
	if (s_vpn)
		natt_mode = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_NAT_TRAVERSAL_MODE);

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("NAT-T when available (default)"), 1, NM_VPNC_NATT_MODE_NATT, -1);
	if ((active < 0) && natt_mode) {
		if (!strcmp (natt_mode, NM_VPNC_NATT_MODE_NATT))
			active = 0;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("NAT-T always"), 1, NM_VPNC_NATT_MODE_NATT_ALWAYS, -1);
	if ((active < 0) && natt_mode) {
		if (!strcmp (natt_mode, NM_VPNC_NATT_MODE_NATT_ALWAYS))
			active = 1;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("Cisco UDP"), 1, NM_VPNC_NATT_MODE_CISCO, -1);
	if ((active < 0) && natt_mode) {
		if (!strcmp (natt_mode, NM_VPNC_NATT_MODE_CISCO))
			active = 2;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("Disabled"), 1, NM_VPNC_NATT_MODE_NONE, -1);
	if ((active < 0) && natt_mode) {
		if (!strcmp (natt_mode, NM_VPNC_NATT_MODE_NONE))
			active = 3;
	}

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "natt_combo"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
	g_object_unref (store);
	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 0 : active);
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	active = -1;
	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
	if (s_vpn)
		ike_dh_group = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_DHGROUP);

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("DH Group 1"), 1, NM_VPNC_DHGROUP_DH1, -1);
	if ((active < 0) && ike_dh_group) {
		if (!strcmp (ike_dh_group, NM_VPNC_DHGROUP_DH1))
			active = 0;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("DH Group 2 (default)"), 1, NM_VPNC_DHGROUP_DH2, -1);
	if ((active < 0) && ike_dh_group) {
		if (!strcmp (ike_dh_group, NM_VPNC_DHGROUP_DH2))
			active = 1;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("DH Group 5"), 1, NM_VPNC_DHGROUP_DH5, -1);
	if ((active < 0) && ike_dh_group) {
		if (!strcmp (ike_dh_group, NM_VPNC_DHGROUP_DH5))
			active = 2;
	}

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dhgroup_combo"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
	g_object_unref (store);
	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 1 : active);
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	/* Local Port */
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "local_port_spinbutton"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_LOCAL_PORT);
		if (value) {
			long int tmp;

			errno = 0;
			tmp = strtol (value, NULL, 10);
			if (errno != 0 || tmp < 0 || tmp > 65535)
				tmp = 0;
			widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "local_port_spinbutton"));
			gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), (gdouble) tmp);
		}
	}
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (spinbutton_changed_cb), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "disable_dpd_checkbutton"));
	g_return_val_if_fail (widget != NULL, FALSE);
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_DPD_IDLE_TIMEOUT);
		if (value) {
			long int tmp;

			errno = 0;
			tmp = strtol (value, NULL, 10);
			if (tmp >= 0 && tmp <= G_MAXUINT32 && errno == 0)
				priv->orig_dpd_timeout = (guint32) tmp;

			if (priv->orig_dpd_timeout == 0)
				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
		}
	}
	g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (stuff_changed_cb), self);

	/* Perfect Forward Secrecy combo */
	active = -1;
	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
	if (s_vpn)
		pfs_group = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_PERFECT_FORWARD);

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("Server (default)"), 1, NM_VPNC_PFS_SERVER, -1);
	if ((active < 0) && pfs_group) {
		if (!strcmp (pfs_group, NM_VPNC_PFS_SERVER))
			active = 0;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("None"), 1, NM_VPNC_PFS_NOPFS, -1);
	if ((active < 0) && pfs_group) {
		if (!strcmp (pfs_group, NM_VPNC_PFS_NOPFS))
			active = 1;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("DH Group 1"), 1, NM_VPNC_PFS_DH1, -1);
	if ((active < 0) && pfs_group) {
		if (!strcmp (pfs_group, NM_VPNC_PFS_DH1))
			active = 2;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("DH Group 2"), 1, NM_VPNC_PFS_DH2, -1);
	if ((active < 0) && pfs_group) {
		if (!strcmp (pfs_group, NM_VPNC_PFS_DH2))
			active = 3;
	}

	gtk_list_store_append (store, &iter);
	gtk_list_store_set (store, &iter, 0, _("DH Group 5"), 1, NM_VPNC_PFS_DH5, -1);
	if ((active < 0) && pfs_group) {
		if (!strcmp (pfs_group, NM_VPNC_PFS_DH5))
			active = 4;
	}

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "pfsecrecy_combo"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, GTK_WIDGET (widget));
	gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));
	g_object_unref (store);
	gtk_combo_box_set_active (GTK_COMBO_BOX (widget), active < 0 ? 0 : active);
	g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "show_passwords_checkbutton"));
	g_return_val_if_fail (widget != NULL, FALSE);
	g_signal_connect (G_OBJECT (widget), "toggled",
	                  (GCallback) show_toggled_cb,
	                  self);

	/* hybrid auth */

	enabled = FALSE;
	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "hybrid_checkbutton"));
	g_return_val_if_fail (widget != NULL, FALSE);
	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_AUTHMODE);
		if (value && !strcmp("hybrid", value)) {
			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
			enabled = TRUE;
		}
	}
	g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (hybrid_toggled_cb), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ca_file_chooser"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_size_group_add_widget (priv->group, widget);
	gtk_widget_set_sensitive (widget, enabled);
	gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
	gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget),
	                                   _("Choose a Certificate Authority (CA) certificate…"));

	filter = gtk_file_filter_new ();
	gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME, cert_filter, NULL, NULL);
	gtk_file_filter_set_name (filter, _("PEM certificates (*.pem, *.crt, *.cer)"));
	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter);

	if (s_vpn) {
		value = nm_setting_vpn_get_data_item (s_vpn, NM_VPNC_KEY_CA_FILE);
		if (value && strlen (value))
			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
	}
	g_signal_connect (G_OBJECT (widget), "file-set", G_CALLBACK (stuff_changed_cb), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "cafile_label"));
	g_return_val_if_fail (widget != NULL, FALSE);
	gtk_widget_set_sensitive (widget, enabled);

	/* advanced dialog */

	priv->advanced_dialog = GTK_WIDGET (gtk_builder_get_object (priv->builder, "vpnc-advanced-dialog"));
	g_return_val_if_fail (priv->advanced_dialog != NULL, FALSE);

	g_signal_connect (G_OBJECT (priv->advanced_dialog), "delete-event",
	                  G_CALLBACK (gtk_widget_hide_on_delete), self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "advanced_button"));
	g_return_val_if_fail (widget != NULL, FALSE);
	g_signal_connect (G_OBJECT (widget), "clicked",
	                  (GCallback) toggle_advanced_dialog_cb,
	                  self);

	widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "apply_button"));
	g_return_val_if_fail (widget != NULL, FALSE);
	g_signal_connect (G_OBJECT (widget), "clicked",
	                  (GCallback) toggle_advanced_dialog_cb,
	                  self);
	return TRUE;
}