static void
test_setting_vpn_items (void)
{
	NMSettingVPN *s_vpn;

	s_vpn = (NMSettingVPN *) nm_setting_vpn_new ();
	ASSERT (s_vpn != NULL,
	        "vpn-items",
	        "error creating vpn setting");

	nm_setting_vpn_add_data_item (s_vpn, "foobar1", "blahblah1");
	nm_setting_vpn_add_data_item (s_vpn, "foobar2", "blahblah2");
	nm_setting_vpn_add_data_item (s_vpn, "foobar3", "blahblah3");
	nm_setting_vpn_add_data_item (s_vpn, "foobar4", "blahblah4");

	/* Ensure that added values are all present */
	nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_func, "vpn-data");
	nm_setting_vpn_remove_data_item (s_vpn, "foobar1");
	nm_setting_vpn_remove_data_item (s_vpn, "foobar2");
	nm_setting_vpn_remove_data_item (s_vpn, "foobar3");
	nm_setting_vpn_remove_data_item (s_vpn, "foobar4");

	nm_setting_vpn_add_secret (s_vpn, "foobar1", "blahblah1");
	nm_setting_vpn_add_secret (s_vpn, "foobar2", "blahblah2");
	nm_setting_vpn_add_secret (s_vpn, "foobar3", "blahblah3");
	nm_setting_vpn_add_secret (s_vpn, "foobar4", "blahblah4");

	/* Ensure that added values are all present */
	nm_setting_vpn_foreach_secret (s_vpn, vpn_check_func, "vpn-secrets");
	nm_setting_vpn_remove_secret (s_vpn, "foobar1");
	nm_setting_vpn_remove_secret (s_vpn, "foobar2");
	nm_setting_vpn_remove_secret (s_vpn, "foobar3");
	nm_setting_vpn_remove_secret (s_vpn, "foobar4");

	/* Try to add some blank values and make sure they are rejected */
	nm_setting_vpn_add_data_item (s_vpn, NULL, NULL);
	nm_setting_vpn_add_data_item (s_vpn, "", "");
	nm_setting_vpn_add_data_item (s_vpn, "foobar1", NULL);
	nm_setting_vpn_add_data_item (s_vpn, "foobar1", "");
	nm_setting_vpn_add_data_item (s_vpn, NULL, "blahblah1");
	nm_setting_vpn_add_data_item (s_vpn, "", "blahblah1");

	nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_empty_func, "vpn-data-empty");

	/* Try to add some blank secrets and make sure they are rejected */
	nm_setting_vpn_add_secret (s_vpn, NULL, NULL);
	nm_setting_vpn_add_secret (s_vpn, "", "");
	nm_setting_vpn_add_secret (s_vpn, "foobar1", NULL);
	nm_setting_vpn_add_secret (s_vpn, "foobar1", "");
	nm_setting_vpn_add_secret (s_vpn, NULL, "blahblah1");
	nm_setting_vpn_add_secret (s_vpn, "", "blahblah1");

	nm_setting_vpn_foreach_secret (s_vpn, vpn_check_empty_func, "vpn-secrets-empty");

	g_object_unref (s_vpn);
}
static gboolean
write_connection_to_child (int fd, NMConnection *connection, GError **error)
{
	NMSettingVPN *s_vpn;
	WriteItemInfo info = { .fd = fd, .secret = FALSE, .error = error };

	s_vpn = nm_connection_get_setting_vpn (connection);
	if (!s_vpn) {
		g_set_error_literal (error,
		                     NM_SECRET_AGENT_ERROR,
		                     NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
		                     "Connection had no VPN setting");
		return FALSE;
	}

	nm_setting_vpn_foreach_data_item (s_vpn, write_one_key_val, &info);
	if (error && *error)
		return FALSE;

	info.secret = TRUE;
	nm_setting_vpn_foreach_secret (s_vpn, write_one_key_val, &info);
	if (error && *error)
		return FALSE;

	if (!write_item (fd, "DONE\n\n", error))
		return FALSE;

	return TRUE;
}
static void
test_items (const char *detail, NMSettingVPN *s_vpn, const Item *items, gboolean secrets)
{
	const Item *iter;
	guint32 expected_count = 0, actual_count = 0;
	const char *value;

	for (iter = items; iter->name; iter++) {
		if (secrets)
			value = nm_setting_vpn_get_secret (s_vpn, iter->name);
		else
			value = nm_setting_vpn_get_data_item (s_vpn, iter->name);

		if (!iter->value) {
			ASSERT (value == NULL, detail, "unexpected item '%s'", iter->name);
		} else {
			ASSERT (value != NULL, detail, "unexpected missing value for item %s", iter->name);
			ASSERT (strcmp (value, iter->value) == 0, detail, "unexpected value for item %s (%s != %s",
			        iter->name, value, iter->value);
			expected_count++;
		}
	}

	if (secrets)
		nm_setting_vpn_foreach_secret (s_vpn, item_count_func, &actual_count);
	else
		nm_setting_vpn_foreach_data_item (s_vpn, item_count_func, &actual_count);

	ASSERT (actual_count == expected_count,
	        detail, "unexpected number of items (got %d, expected %d)", actual_count, expected_count);
}
static void
write_one_secret_to_keyring (NMSetting *setting,
                             const char *key,
                             const GValue *value,
                             GParamFlags flags,
                             gpointer user_data)
{
	Request *r = user_data;
	GType type = G_VALUE_TYPE (value);
	const char *secret;

	/* Non-secrets obviously don't get saved in the keyring */
	if (!(flags & NM_SETTING_PARAM_SECRET))
		return;

	if (NM_IS_SETTING_VPN (setting) && (g_strcmp0 (key, NM_SETTING_VPN_SECRETS) == 0)) {
		g_return_if_fail (type == DBUS_TYPE_G_MAP_OF_STRING);

		/* Process VPN secrets specially since it's a hash of secrets, not just one */
		nm_setting_vpn_foreach_secret (NM_SETTING_VPN (setting),
		                               vpn_secret_iter_cb,
		                               r);
	} else {
		g_return_if_fail (type == G_TYPE_STRING);
		secret = g_value_get_string (value);
		if (secret && strlen (secret))
			save_one_secret (r, setting, key, secret, NULL);
	}
}
static gboolean
nm_sstp_secrets_validate (NMSettingVpn *s_vpn, GError **error)
{
	ValidateInfo info = { &valid_secrets[0], error, FALSE };

	nm_setting_vpn_foreach_secret (s_vpn, validate_one_property, &info);
	if (!info.have_items) {
		g_set_error (error,
		             NM_VPN_PLUGIN_ERROR,
		             NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
		             "%s",
		             _("No VPN secrets!"));
		return FALSE;
	}

	return *error ? FALSE : TRUE;
}