/**
 * nm_setting_proxy_get_method:
 * @setting: the #NMSettingProxy
 *
 * Returns the proxy configuration method. By default the value is "NONE".
 * "NONE" should be selected for a connection intended for direct network
 * access.
 *
 * Returns: the proxy configuration method
 *
 * Since: 1.6
 **/
NMSettingProxyMethod
nm_setting_proxy_get_method (NMSettingProxy *setting)
{
	g_return_val_if_fail (NM_IS_SETTING_PROXY (setting), NM_SETTING_PROXY_METHOD_NONE);

	return NM_SETTING_PROXY_GET_PRIVATE (setting)->method;
}
/**
 * nm_setting_proxy_get_pac_script:
 * @setting: the #NMSettingProxy
 *
 * Returns: the PAC Script
 *
 * Since: 1.6
 **/
const char *
nm_setting_proxy_get_pac_script (NMSettingProxy *setting)
{
	g_return_val_if_fail (NM_IS_SETTING_PROXY (setting), NULL);

	return NM_SETTING_PROXY_GET_PRIVATE (setting)->pac_script;
}
static void
set_property (GObject *object, guint prop_id,
              const GValue *value, GParamSpec *pspec)
{
	NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE (object);

	switch (prop_id) {
	case PROP_METHOD:
		priv->method = g_value_get_int (value);
		break;
	case PROP_BROWSER_ONLY:
		priv->browser_only = g_value_get_boolean (value);
		break;
	case PROP_PAC_URL:
		g_free (priv->pac_url);
		priv->pac_url = g_value_dup_string (value);
		break;
	case PROP_PAC_SCRIPT:
		g_free (priv->pac_script);
		priv->pac_script = g_value_dup_string (value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
/**
 * nm_setting_proxy_get_socks_version_5:
 * @setting: the #NMSettingProxy
 *
 * Returns: TRUE if SOCKS version is 5.
 * FALSE if SOCKS version is 4.
 *
 * Since: 1.4
**/
gboolean
nm_setting_proxy_get_socks_version_5 (NMSettingProxy *setting)
{
	g_return_val_if_fail (NM_IS_SETTING_PROXY (setting), FALSE);

	return NM_SETTING_PROXY_GET_PRIVATE (setting)->socks_version_5;
}
/**
 * nm_setting_proxy_get_browser_only:
 * @setting: the #NMSettingProxy
 *
 * Returns: TRUE if this proxy configuration is only for Browser
 * clients/schemes otherwise FALSE.
 *
 * Since: 1.6
 **/
gboolean
nm_setting_proxy_get_browser_only (NMSettingProxy *setting)
{
	g_return_val_if_fail (NM_IS_SETTING_PROXY (setting), FALSE);

	return NM_SETTING_PROXY_GET_PRIVATE (setting)->browser_only;
}
/**
 * nm_setting_proxy_get_socks_port:
 * @setting: the #NMSettingProxy
 *
 * Returns: the SOCKS port number
 *
 * Since: 1.4
 **/
guint32
nm_setting_proxy_get_socks_port (NMSettingProxy *setting)
{
	g_return_val_if_fail (NM_IS_SETTING_PROXY (setting), 0);

	return NM_SETTING_PROXY_GET_PRIVATE (setting)->socks_port;
}
/**
 * nm_setting_proxy_get_socks_proxy:
 * @setting: the #NMSettingProxy
 *
 * Returns: the SOCKS proxy
 *
 * Since: 1.4
 **/
const char *
nm_setting_proxy_get_socks_proxy (NMSettingProxy *setting)
{
	g_return_val_if_fail (NM_IS_SETTING_PROXY (setting), NULL);

	return NM_SETTING_PROXY_GET_PRIVATE (setting)->socks_proxy;
}
/**
 * nm_setting_proxy_get_http_default:
 * @setting: the #NMSettingProxy
 *
 * Returns: TRUE if HTTP Proxy is default for all
 * protocols. FALSE if not.
 *
 * Since: 1.4
 **/
gboolean
nm_setting_proxy_get_http_default (NMSettingProxy *setting)
{
	g_return_val_if_fail (NM_IS_SETTING_PROXY (setting), FALSE);

	return NM_SETTING_PROXY_GET_PRIVATE (setting)->http_default;
}
static void
nm_setting_proxy_init (NMSettingProxy *setting)
{
	NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE (setting);

	priv->method = NM_SETTING_PROXY_METHOD_NONE;
	priv->no_proxy_for = g_ptr_array_new_with_free_func (g_free);
}
static void
finalize (GObject *object)
{
	NMSettingProxy *self = NM_SETTING_PROXY (object);
	NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE (self);

	g_free (priv->pac_url);
	g_free (priv->pac_script);

	G_OBJECT_CLASS (nm_setting_proxy_parent_class)->finalize (object);
}
static void
finalize (GObject *object)
{
	NMSettingProxy *self = NM_SETTING_PROXY (object);
	NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE (self);

	g_free (priv->http_proxy);
	g_free (priv->ssl_proxy);
	g_free (priv->ftp_proxy);
	g_free (priv->socks_proxy);
	g_free (priv->pac_url);
	g_free (priv->pac_script);

	g_ptr_array_unref (priv->no_proxy_for);

	G_OBJECT_CLASS (nm_setting_proxy_parent_class)->finalize (object);
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE (setting);
	NMSettingProxyMethod method;

	method = priv->method;

	if (!NM_IN_SET (method,
	                NM_SETTING_PROXY_METHOD_NONE,
	                NM_SETTING_PROXY_METHOD_AUTO)) {
		g_set_error (error,
		             NM_CONNECTION_ERROR,
		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
		             _("invalid proxy method"));
		g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL);
		return FALSE;
	}

	if (method != NM_SETTING_PROXY_METHOD_AUTO) {
		if (priv->pac_url) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL);
			return FALSE;
		}

		if (priv->pac_script) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT);
			return FALSE;
		}
	}

	if (priv->pac_script) {
		if (strlen (priv->pac_script) > 1*1024*1024) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("the script is too large"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT);
			return FALSE;
		}
		if (!g_utf8_validate (priv->pac_script, -1, NULL)) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("the script is not valid utf8"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT);
			return FALSE;
		}
		if (!strstr (priv->pac_script, "FindProxyForURL")) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("the script lacks FindProxyForURL function"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT);
			return FALSE;
		}
	}

	return TRUE;
}
static void
set_property (GObject *object, guint prop_id,
              const GValue *value, GParamSpec *pspec)
{
	NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE (object);

	switch (prop_id) {
	case PROP_METHOD:
		priv->method = g_value_get_int (value);
		break;
	case PROP_HTTP_PROXY:
		g_free (priv->http_proxy);
		priv->http_proxy = g_value_dup_string (value);
		break;
	case PROP_HTTP_PORT:
		priv->http_port = g_value_get_uint (value);
		break;
	case PROP_HTTP_DEFAULT:
		priv->http_default = g_value_get_boolean (value);
		break;
	case PROP_SSL_PROXY:
		g_free (priv->ssl_proxy);
		/* Check if HTTP Proxy has been set for all Protocols */
		priv->ssl_proxy = priv->http_default == TRUE ? g_strdup (priv->http_proxy) : g_value_dup_string (value);
		break;
	case PROP_SSL_PORT:
		priv->ssl_port = priv->http_default == TRUE ? priv->http_port : g_value_get_uint (value);
		break;
	case PROP_FTP_PROXY:
		g_free (priv->ftp_proxy);
		priv->ftp_proxy = priv->http_default == TRUE ? g_strdup (priv->http_proxy) : g_value_dup_string (value);
		break;
	case PROP_FTP_PORT:
		priv->ftp_port = priv->http_default == TRUE ? priv->http_port : g_value_get_uint (value);
		break;
	case PROP_SOCKS_PROXY:
		g_free (priv->socks_proxy);
		priv->socks_proxy = priv->http_default == TRUE ? g_strdup (priv->http_proxy) : g_value_dup_string (value);
		break;
	case PROP_SOCKS_PORT:
		priv->socks_port = priv->http_default == TRUE ? priv->http_port : g_value_get_uint (value);
		break;
	case PROP_SOCKS_VERSION_5:
		priv->socks_version_5 = g_value_get_boolean (value);
		break;
	case PROP_NO_PROXY_FOR:
		g_ptr_array_unref (priv->no_proxy_for);
		priv->no_proxy_for = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value));
		break;
	case PROP_PAC_URL:
		g_free (priv->pac_url);
		priv->pac_url = g_value_dup_string (value);
		break;
	case PROP_PAC_SCRIPT:
		g_free (priv->pac_script);
		priv->pac_script = g_value_dup_string (value);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}
static gboolean
verify (NMSetting *setting, NMConnection *connection, GError **error)
{
	NMSettingProxyPrivate *priv = NM_SETTING_PROXY_GET_PRIVATE (setting);
	NMSettingProxyMethod method;

	method = priv->method;
	if (method == NM_SETTING_PROXY_METHOD_AUTO || method == NM_SETTING_PROXY_METHOD_NONE) {
		if (priv->http_proxy) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_HTTP_PROXY);
			return FALSE;
		}

		if (priv->http_port) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_HTTP_PORT);
			return FALSE;
		}

		if (priv->http_default) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_HTTP_DEFAULT);
			return FALSE;
		}

		if (priv->ssl_proxy) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_SSL_PROXY);
			return FALSE;
		}

		if (priv->ssl_port) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_SSL_PORT);
			return FALSE;
		}

		if (priv->ftp_proxy) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_FTP_PROXY);
			return FALSE;
		}

		if (priv->ftp_port) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_FTP_PORT);
			return FALSE;
		}

		if (priv->socks_proxy) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_SOCKS_PROXY);
			return FALSE;
		}

		if (priv->socks_port) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_SOCKS_PORT);
			return FALSE;
		}

		if (priv->socks_version_5) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_SOCKS_VERSION_5);
			return FALSE;
		}

		if (priv->no_proxy_for->len > 0) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=auto/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_NO_PROXY_FOR);
			return FALSE;
		}

		if (method == NM_SETTING_PROXY_METHOD_NONE) {
			if (priv->pac_url) {
				g_set_error (error,
				             NM_CONNECTION_ERROR,
				             NM_CONNECTION_ERROR_INVALID_PROPERTY,
				             _("this property is not allowed for method=manual/none"));
				g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL);
				return FALSE;
			}

			if (priv->pac_script) {
				g_set_error (error,
				             NM_CONNECTION_ERROR,
				             NM_CONNECTION_ERROR_INVALID_PROPERTY,
				             _("this property is not allowed for method=manual/none"));
				g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT);
				return FALSE;
			}
		}
	} else if (method == NM_SETTING_PROXY_METHOD_MANUAL) {
		if (priv->pac_url) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=manual/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_URL);
			return FALSE;
		}

		if (priv->pac_script) {
			g_set_error (error,
			             NM_CONNECTION_ERROR,
			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
			             _("this property is not allowed for method=manual/none"));
			g_prefix_error (error, "%s.%s: ", NM_SETTING_PROXY_SETTING_NAME, NM_SETTING_PROXY_PAC_SCRIPT);
			return FALSE;
		}
	} else
		return FALSE;

	return TRUE;
}