libsoup r1048 - in trunk: . libsoup



Author: danw
Date: Fri Jan 18 14:53:35 2008
New Revision: 1048
URL: http://svn.gnome.org/viewvc/libsoup?rev=1048&view=rev

Log:
	* libsoup/soup-auth-domain.c
	(soup_auth_domain_set_generic_auth_callback):
	(soup_auth_domain_check_password): add a new generic auth callback
	that can be used with any subclass to do cleartext password
	checking against messages. Suggested by Mathias Hasselmann.

	* libsoup/soup-auth-domain-basic.c: Implement generic auth

	* libsoup/soup-auth-domain-digest.c: Implement generic auth.
	(soup_auth_domain_digest_evil_check_password): Gone, use the
	generic version now.


Modified:
   trunk/ChangeLog
   trunk/libsoup/soup-auth-domain-basic.c
   trunk/libsoup/soup-auth-domain-digest.c
   trunk/libsoup/soup-auth-domain-digest.h
   trunk/libsoup/soup-auth-domain.c
   trunk/libsoup/soup-auth-domain.h

Modified: trunk/libsoup/soup-auth-domain-basic.c
==============================================================================
--- trunk/libsoup/soup-auth-domain-basic.c	(original)
+++ trunk/libsoup/soup-auth-domain-basic.c	Fri Jan 18 14:53:35 2008
@@ -42,11 +42,15 @@
 
 G_DEFINE_TYPE (SoupAuthDomainBasic, soup_auth_domain_basic, SOUP_TYPE_AUTH_DOMAIN)
 
-static char *accepts   (SoupAuthDomain *domain,
-			SoupMessage    *msg,
-			const char     *header);
-static char *challenge (SoupAuthDomain *domain,
-			SoupMessage    *msg);
+static char    *accepts        (SoupAuthDomain *domain,
+				SoupMessage    *msg,
+				const char     *header);
+static char    *challenge      (SoupAuthDomain *domain,
+				SoupMessage    *msg);
+static gboolean check_password (SoupAuthDomain *domain,
+				SoupMessage    *msg,
+				const char     *username,
+				const char     *password);
 
 static void set_property (GObject *object, guint prop_id,
 			  const GValue *value, GParamSpec *pspec);
@@ -79,8 +83,9 @@
 
 	g_type_class_add_private (basic_class, sizeof (SoupAuthDomainBasicPrivate));
 
-	auth_domain_class->accepts   = accepts;
-	auth_domain_class->challenge = challenge;
+	auth_domain_class->accepts        = accepts;
+	auth_domain_class->challenge      = challenge;
+	auth_domain_class->check_password = check_password;
 
 	object_class->finalize     = finalize;
 	object_class->set_property = set_property;
@@ -241,40 +246,53 @@
 	g_free (pw);
 }
 
-static char *
-accepts (SoupAuthDomain *domain, SoupMessage *msg, const char *header)
+static gboolean
+parse_basic (SoupMessage *msg, const char *header,
+	     char **username, char **password)
 {
-	SoupAuthDomainBasicPrivate *priv =
-		SOUP_AUTH_DOMAIN_BASIC_GET_PRIVATE (domain);
 	char *decoded, *colon;
 	gsize len, plen;
-	char *username, *password;
-	gboolean ok = FALSE;
-
-	if (!priv->auth_callback)
-		return NULL;
 
 	if (strncmp (header, "Basic ", 6) != 0)
-		return NULL;
+		return FALSE;
 
 	decoded = (char *)g_base64_decode (header + 6, &len);
 	if (!decoded)
-		return NULL;
+		return FALSE;
 
 	colon = memchr (decoded, ':', len);
 	if (!colon) {
 		pw_free (decoded);
-		return NULL;
+		return FALSE;
 	}
 	*colon = '\0';
 	plen = len - (colon - decoded) - 1;
 
-	password = g_strndup (colon + 1, plen);
+	*password = g_strndup (colon + 1, plen);
 	memset (colon + 1, 0, plen);
-	username = decoded;
+	*username = decoded;
+	return TRUE;
+}
+
+static char *
+accepts (SoupAuthDomain *domain, SoupMessage *msg, const char *header)
+{
+	SoupAuthDomainBasicPrivate *priv =
+		SOUP_AUTH_DOMAIN_BASIC_GET_PRIVATE (domain);
+	char *username, *password;
+	gboolean ok = FALSE;
+
+	if (!parse_basic (msg, header, &username, &password))
+		return NULL;
+
+	if (priv->auth_callback) {
+		ok = priv->auth_callback (domain, msg, username, password,
+					  priv->auth_data);
+	} else {
+		ok = soup_auth_domain_try_generic_auth_callback (
+			domain, msg, username);
+	}
 
-	ok = priv->auth_callback (domain, msg, username, password,
-				  priv->auth_data);
 	pw_free (password);
 
 	if (ok)
@@ -292,3 +310,25 @@
 	return g_strdup_printf ("Basic realm=\"%s\"",
 				soup_auth_domain_get_realm (domain));
 }
+
+static gboolean
+check_password (SoupAuthDomain *domain,
+		SoupMessage    *msg,
+		const char     *username,
+		const char     *password)
+{
+	const char *header;
+	char *msg_username, *msg_password;
+	gboolean ok;
+
+	header = soup_message_headers_get (msg->request_headers, "Authorization");
+	if (!parse_basic (msg, header, &msg_username, &msg_password))
+		return FALSE;
+
+	ok = (!strcmp (username, msg_username) &&
+	      !strcmp (password, msg_password));
+	g_free (msg_username);
+	pw_free (msg_password);
+
+	return ok;
+}

Modified: trunk/libsoup/soup-auth-domain-digest.c
==============================================================================
--- trunk/libsoup/soup-auth-domain-digest.c	(original)
+++ trunk/libsoup/soup-auth-domain-digest.c	Fri Jan 18 14:53:35 2008
@@ -47,11 +47,15 @@
 
 G_DEFINE_TYPE (SoupAuthDomainDigest, soup_auth_domain_digest, SOUP_TYPE_AUTH_DOMAIN)
 
-static char *accepts   (SoupAuthDomain *domain,
-			SoupMessage    *msg,
-			const char     *header);
-static char *challenge (SoupAuthDomain *domain,
-			SoupMessage    *msg);
+static char    *accepts        (SoupAuthDomain *domain,
+				SoupMessage    *msg,
+				const char     *header);
+static char    *challenge      (SoupAuthDomain *domain,
+				SoupMessage    *msg);
+static gboolean check_password (SoupAuthDomain *domain,
+				SoupMessage    *msg,
+				const char     *username,
+				const char     *password);
 
 static void set_property (GObject *object, guint prop_id,
 			  const GValue *value, GParamSpec *pspec);
@@ -84,8 +88,9 @@
 
 	g_type_class_add_private (digest_class, sizeof (SoupAuthDomainDigestPrivate));
 
-	auth_domain_class->accepts   = accepts;
-	auth_domain_class->challenge = challenge;
+	auth_domain_class->accepts        = accepts;
+	auth_domain_class->challenge      = challenge;
+	auth_domain_class->check_password = check_password;
 
 	object_class->finalize     = finalize;
 	object_class->set_property = set_property;
@@ -229,40 +234,32 @@
 	g_object_notify (G_OBJECT (domain), SOUP_AUTH_DOMAIN_DIGEST_AUTH_DATA);
 }
 
-static char *
-accepts (SoupAuthDomain *domain, SoupMessage *msg, const char *header)
+static gboolean
+check_hex_urp (SoupAuthDomain *domain, SoupMessage *msg,
+	       GHashTable *params, const char *username,
+	       const char *hex_urp)
 {
-	SoupAuthDomainDigestPrivate *priv =
-		SOUP_AUTH_DOMAIN_DIGEST_GET_PRIVATE (domain);
-	GHashTable *params;
-	const char *uri, *qop, *realm, *username;
+	const char *uri, *qop, *realm, *msg_username;
 	const char *nonce, *nc, *cnonce, *response;
-	char *hex_urp, hex_a1[33], computed_response[33], *ret_user;
+	char hex_a1[33], computed_response[33];
 	int nonce_count;
 	SoupURI *dig_uri, *req_uri;
-	gboolean accept = FALSE;
-
-	if (!priv->auth_callback)
-		return NULL;
-
-	if (strncmp (header, "Digest ", 7) != 0)
-		return NULL;
 
-	params = soup_header_parse_param_list (header + 7);
-	if (!params)
-		return NULL;
+	msg_username = g_hash_table_lookup (params, "username");
+	if (!msg_username || strcmp (msg_username, username) != 0)
+		return FALSE;
 
 	/* Check uri */
 	uri = g_hash_table_lookup (params, "uri");
 	if (!uri)
-		goto DONE;
+		return FALSE;
 
 	req_uri = soup_message_get_uri (msg);
 	dig_uri = soup_uri_new (uri);
 	if (dig_uri) {
 		if (!soup_uri_equal (dig_uri, req_uri)) {
 			soup_uri_free (dig_uri);
-			goto DONE;
+			return FALSE;
 		}
 		soup_uri_free (dig_uri);
 	} else {	
@@ -271,7 +268,7 @@
 		req_path = soup_uri_to_string (req_uri, TRUE);
 		if (strcmp (uri, req_path) != 0) {
 			g_free (req_path);
-			goto DONE;
+			return FALSE;
 		}
 		g_free (req_path);
 	}
@@ -279,46 +276,75 @@
 	/* Check qop; we only support "auth" for now */
 	qop = g_hash_table_lookup (params, "qop");
 	if (!qop || strcmp (qop, "auth") != 0)
-		goto DONE;
+		return FALSE;
 
 	/* Check realm */
 	realm = g_hash_table_lookup (params, "realm");
 	if (!realm || strcmp (realm, soup_auth_domain_get_realm (domain)) != 0)
-		goto DONE;
+		return FALSE;
 
-	username = g_hash_table_lookup (params, "username");
-	if (!username)
-		goto DONE;
 	nonce = g_hash_table_lookup (params, "nonce");
 	if (!nonce)
-		goto DONE;
+		return FALSE;
 	nc = g_hash_table_lookup (params, "nc");
 	if (!nc)
-		goto DONE;
+		return FALSE;
 	nonce_count = atoi (nc);
 	if (nonce_count <= 0)
-		goto DONE;
+		return FALSE;
 	cnonce = g_hash_table_lookup (params, "cnonce");
 	if (!cnonce)
-		goto DONE;
+		return FALSE;
 	response = g_hash_table_lookup (params, "response");
 	if (!response)
-		goto DONE;
+		return FALSE;
+
+	soup_auth_digest_compute_hex_a1 (hex_urp,
+					 SOUP_AUTH_DIGEST_ALGORITHM_MD5,
+					 nonce, cnonce, hex_a1);
+	soup_auth_digest_compute_response (msg->method, uri,
+					   hex_a1,
+					   SOUP_AUTH_DIGEST_QOP_AUTH,
+					   nonce, cnonce, nonce_count,
+					   computed_response);
+	return strcmp (response, computed_response) == 0;
+}
+
+static char *
+accepts (SoupAuthDomain *domain, SoupMessage *msg, const char *header)
+{
+	SoupAuthDomainDigestPrivate *priv =
+		SOUP_AUTH_DOMAIN_DIGEST_GET_PRIVATE (domain);
+	GHashTable *params;
+	const char *username;
+	gboolean accept = FALSE;
+	char *ret_user;
+
+	if (strncmp (header, "Digest ", 7) != 0)
+		return NULL;
+
+	params = soup_header_parse_param_list (header + 7);
+	if (!params)
+		return NULL;
+
+	username = g_hash_table_lookup (params, "username");
+	if (!username) {
+		soup_header_free_param_list (params);
+		return NULL;
+	}
 
-	hex_urp = priv->auth_callback (domain, msg, username, priv->auth_data);
-	if (hex_urp) {
-		soup_auth_digest_compute_hex_a1 (hex_urp,
-						 SOUP_AUTH_DIGEST_ALGORITHM_MD5,
-						 nonce, cnonce, hex_a1);
+	if (priv->auth_callback) {
+		char *hex_urp;
+
+		hex_urp = priv->auth_callback (domain, msg, username,
+					       priv->auth_data);
+		accept = check_hex_urp (domain, msg, params, username, hex_urp);
 		g_free (hex_urp);
-		soup_auth_digest_compute_response (msg->method, uri, hex_a1,
-						   SOUP_AUTH_DIGEST_QOP_AUTH,
-						   nonce, cnonce, nonce_count,
-						   computed_response);
-		accept = (strcmp (response, computed_response) == 0);
+	} else {
+		accept = soup_auth_domain_try_generic_auth_callback (
+			domain, msg, username);
 	}
 
- DONE:
 	ret_user = accept ? g_strdup (username) : NULL;
 	soup_header_free_param_list (params);
 	return ret_user;
@@ -378,77 +404,36 @@
 	return g_strdup (hex_urp);
 }
 
-static char *
-evil_auth_callback (SoupAuthDomain *domain, SoupMessage *msg,
-		    const char *username, gpointer encoded_password)
-{
-	return g_strdup (encoded_password);
-}
-
-/**
- * soup_auth_domain_digest_evil_check_password:
- * @domain: the auth domain
- * @msg: the possibly-authenticated request
- * @username: the username to check @msg against
- * @password: the password to check @msg against
- *
- * Checks if @msg correctly authenticates @username via @password in
- * @domain.
- *
- * Don't use this method; it's evil. It requires you to have a
- * cleartext password database, which means that if your server is
- * compromised, the attackers will have access to all of your users'
- * passwords, which may also be their passwords on other servers. It
- * is much better to store the passwords encoded in some format (eg,
- * via soup_auth_domain_digest_encode_password() when using Digest
- * authentication), so that if the server is compromised, the
- * attackers won't be able to use the encoded passwords elsewhere.
- *
- * At any rate, even if you do have a cleartext password database, you
- * still don't need to use this method, as you can just call
- * soup_auth_domain_digest_encode_password() on the cleartext password
- * from the #SoupAuthDomainDigestAuthCallback anyway. This method
- * really only exists so as not to break certain libraries written
- * against libsoup 2.2 whose public APIs depend on the existence of a
- * "check this password against this request" method.
- *
- * Return value: %TRUE if @msg matches @username and @password,
- * %FALSE if not.
- **/
-gboolean
-soup_auth_domain_digest_evil_check_password (SoupAuthDomain *domain,
-					     SoupMessage    *msg,
-					     const char     *username,
-					     const char     *password)
+static gboolean
+check_password (SoupAuthDomain *domain,
+		SoupMessage    *msg,
+		const char     *username,
+		const char     *password)
 {
-	SoupAuthDomainDigestPrivate *priv =
-		SOUP_AUTH_DOMAIN_DIGEST_GET_PRIVATE (domain);
-	char *encoded_password;
 	const char *header;
-	SoupAuthDomainDigestAuthCallback old_callback;
-	gpointer old_data;
-	char *matched_username;
-
-	encoded_password = soup_auth_domain_digest_encode_password (
-		username, soup_auth_domain_get_realm (domain), password);
-
-	old_callback = priv->auth_callback;
-	old_data = priv->auth_data;
-
-	priv->auth_callback = evil_auth_callback;
-	priv->auth_data = encoded_password;
+	GHashTable *params;
+	const char *msg_username;
+	char hex_urp[33];
+	gboolean accept;
 
 	header = soup_message_headers_get (msg->request_headers, "Authorization");
-	matched_username = accepts (domain, msg, header);
-
-	priv->auth_callback = old_callback;
-	priv->auth_data = old_data;
+	if (strncmp (header, "Digest ", 7) != 0)
+		return FALSE;
 
-	g_free (encoded_password);
+	params = soup_header_parse_param_list (header + 7);
+	if (!params)
+		return FALSE;
 
-	if (matched_username) {
-		g_free (matched_username);
-		return TRUE;
-	} else
+	msg_username = g_hash_table_lookup (params, "username");
+	if (!msg_username || strcmp (msg_username, username) != 0) {
+		soup_header_free_param_list (params);
 		return FALSE;
+	}
+
+	soup_auth_digest_compute_hex_urp (username,
+					  soup_auth_domain_get_realm (domain),
+					  password, hex_urp);
+	accept = check_hex_urp (domain, msg, params, username, hex_urp);
+	soup_header_free_param_list (params);
+	return accept;
 }

Modified: trunk/libsoup/soup-auth-domain-digest.h
==============================================================================
--- trunk/libsoup/soup-auth-domain-digest.h	(original)
+++ trunk/libsoup/soup-auth-domain-digest.h	Fri Jan 18 14:53:35 2008
@@ -52,11 +52,4 @@
 						    const char     *realm,
 						    const char     *password);
 
-
-gboolean soup_auth_domain_digest_evil_check_password (SoupAuthDomain *domain,
-						      SoupMessage    *msg,
-						      const char     *username,
-						      const char     *password);
-
-
 #endif /* SOUP_AUTH_DOMAIN_DIGEST_H */

Modified: trunk/libsoup/soup-auth-domain.c
==============================================================================
--- trunk/libsoup/soup-auth-domain.c	(original)
+++ trunk/libsoup/soup-auth-domain.c	Fri Jan 18 14:53:35 2008
@@ -47,6 +47,8 @@
 	PROP_REMOVE_PATH,
 	PROP_FILTER,
 	PROP_FILTER_DATA,
+	PROP_GENERIC_AUTH_CALLBACK,
+	PROP_GENERIC_AUTH_DATA,
 
 	LAST_PROP
 };
@@ -54,10 +56,16 @@
 typedef struct {
 	char *realm;
 	gboolean proxy;
+	SoupPathMap *paths;
+
 	SoupAuthDomainFilter filter;
 	gpointer filter_data;
 	GDestroyNotify filter_dnotify;
-	SoupPathMap *paths;
+
+	SoupAuthDomainGenericAuthCallback auth_callback;
+	gpointer auth_data;
+	GDestroyNotify auth_dnotify;
+
 } SoupAuthDomainPrivate;
 
 #define SOUP_AUTH_DOMAIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_AUTH_DOMAIN, SoupAuthDomainPrivate))
@@ -87,6 +95,8 @@
 
 	if (priv->filter_dnotify)
 		priv->filter_dnotify (priv->filter_data);
+	if (priv->auth_dnotify)
+		priv->auth_dnotify (priv->auth_data);
 
 	G_OBJECT_CLASS (soup_auth_domain_parent_class)->finalize (object);
 }
@@ -142,6 +152,18 @@
 				      "Filter data",
 				      "Data to pass to filter",
 				      G_PARAM_READWRITE));
+	g_object_class_install_property (
+		object_class, PROP_GENERIC_AUTH_CALLBACK,
+		g_param_spec_pointer (SOUP_AUTH_DOMAIN_GENERIC_AUTH_CALLBACK,
+				      "Generic authentication callback",
+				      "An authentication callback that can be used with any SoupAuthDomain subclass",
+				      G_PARAM_READWRITE));
+	g_object_class_install_property (
+		object_class, PROP_GENERIC_AUTH_DATA,
+		g_param_spec_pointer (SOUP_AUTH_DOMAIN_GENERIC_AUTH_DATA,
+				      "Authentication callback data",
+				      "Data to pass to auth callback",
+				      G_PARAM_READWRITE));
 }
 
 static void
@@ -177,6 +199,16 @@
 		}
 		priv->filter_data = g_value_get_pointer (value);
 		break;
+	case PROP_GENERIC_AUTH_CALLBACK:
+		priv->auth_callback = g_value_get_pointer (value);
+		break;
+	case PROP_GENERIC_AUTH_DATA:
+		if (priv->auth_dnotify) {
+			priv->auth_dnotify (priv->auth_data);
+			priv->auth_dnotify = NULL;
+		}
+		priv->auth_data = g_value_get_pointer (value);
+		break;
 	default:
 		break;
 	}
@@ -201,6 +233,12 @@
 	case PROP_FILTER_DATA:
 		g_value_set_pointer (value, priv->filter_data);
 		break;
+	case PROP_GENERIC_AUTH_CALLBACK:
+		g_value_set_pointer (value, priv->auth_callback);
+		break;
+	case PROP_GENERIC_AUTH_DATA:
+		g_value_set_pointer (value, priv->auth_data);
+		break;
 	default:
 		break;
 	}
@@ -256,6 +294,18 @@
 }
 
 /**
+ * SoupAuthDomainFilter:
+ * @domain: a #SoupAuthDomain
+ * @msg: a #SoupMessage
+ * @user_data: the data passed to soup_auth_domain_set_filter()
+ *
+ * The prototype for a #SoupAuthDomain filter; see
+ * soup_auth_domain_set_filter() for details.
+ *
+ * Return value: %TRUE if @msg requires authentication, %FALSE if not.
+ **/
+
+/**
  * soup_auth_domain_set_filter:
  * @domain: a #SoupAuthDomain
  * @filter: the auth filter for @domain
@@ -324,6 +374,105 @@
 }
 
 /**
+ * SoupAuthDomainGenericAuthCallback:
+ * @domain: a #SoupAuthDomain
+ * @msg: the #SoupMessage being authenticated
+ * @username: the username from @msg
+ * @user_data: the data passed to
+ * soup_auth_domain_set_generic_auth_callback()
+ *
+ * The prototype for a #SoupAuthDomain generic authentication callback.
+ *
+ * The callback should look up the user's password, call
+ * soup_auth_domain_check_password(), and use the return value from
+ * that method as its own return value.
+ *
+ * In general, for security reasons, it is preferable to use the
+ * auth-domain-specific auth callbacks (eg,
+ * #SoupAuthDomainBasicAuthCallback and
+ * #SoupAuthDomainDigestAuthCallback), because they don't require
+ * keeping a cleartext password database. Most users will use the same
+ * password for many different sites, meaning if any site with a
+ * cleartext password database is compromised, accounts on other
+ * servers might be compromised as well. For many of the cases where
+ * #SoupServer is used, this is not really relevant, but it may still
+ * be worth considering.
+ *
+ * Return value: %TRUE if @msg is authenticated, %FALSE if not.
+ **/
+
+/**
+ * soup_auth_domain_set_generic_auth_callback:
+ * @domain: a #SoupAuthDomain
+ * @auth_callback: the auth callback
+ * @auth_data: data to pass to @auth_callback
+ * @dnotify: destroy notifier to free @auth_data when @domain
+ * is destroyed
+ *
+ * Sets @auth_callback as an authentication-handling callback for
+ * @domain. Whenever a request comes in to @domain which cannot be
+ * authenticated via a domain-specific auth callback (eg,
+ * #SoupAuthDomainDigestAuthCallback), the generic auth callback
+ * will be invoked. See #SoupAuthDomainGenericAuthCallback for information
+ * on what the callback should do.
+ **/
+void
+soup_auth_domain_set_generic_auth_callback (SoupAuthDomain *domain,
+					    SoupAuthDomainGenericAuthCallback auth_callback,
+					    gpointer        auth_data,
+					    GDestroyNotify  dnotify)
+{
+	SoupAuthDomainPrivate *priv = SOUP_AUTH_DOMAIN_GET_PRIVATE (domain);
+
+	if (priv->auth_dnotify)
+		priv->auth_dnotify (priv->auth_data);
+
+	priv->auth_callback = auth_callback;
+	priv->auth_data = auth_data;
+	priv->auth_dnotify = dnotify;
+
+	g_object_notify (G_OBJECT (domain), SOUP_AUTH_DOMAIN_GENERIC_AUTH_CALLBACK);
+	g_object_notify (G_OBJECT (domain), SOUP_AUTH_DOMAIN_GENERIC_AUTH_DATA);
+}
+
+gboolean
+soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
+					    SoupMessage    *msg,
+					    const char     *username)
+{
+	SoupAuthDomainPrivate *priv = SOUP_AUTH_DOMAIN_GET_PRIVATE (domain);
+
+	if (priv->auth_callback)
+		return priv->auth_callback (domain, msg, username, priv->auth_data);
+	else
+		return FALSE;
+}
+
+/**
+ * soup_auth_domain_check_password:
+ * @domain: a #SoupAuthDomain
+ * @msg: a #SoupMessage
+ * @username: a username
+ * @password: a password
+ *
+ * Checks if @msg authenticates to @domain via @username and
+ * @password. This would normally be called from a
+ * #SoupAuthDomainGenericAuthCallback.
+ *
+ * Return value: whether or not the message is authenticated
+ **/
+gboolean
+soup_auth_domain_check_password (SoupAuthDomain *domain,
+				 SoupMessage    *msg,
+				 const char     *username,
+				 const char     *password)
+{
+	return SOUP_AUTH_DOMAIN_GET_CLASS (domain)->check_password (domain, msg,
+								    username,
+								    password);
+}
+
+/**
  * soup_auth_domain_covers:
  * @domain: a #SoupAuthDomain
  * @msg: a #SoupMessage

Modified: trunk/libsoup/soup-auth-domain.h
==============================================================================
--- trunk/libsoup/soup-auth-domain.h	(original)
+++ trunk/libsoup/soup-auth-domain.h	Fri Jan 18 14:53:35 2008
@@ -23,14 +23,17 @@
 typedef struct {
 	GObjectClass parent_class;
 
-	char *   (*accepts)   (SoupAuthDomain  *domain,
-			       SoupMessage     *msg,
-			       const char      *header);
-	char *   (*challenge) (SoupAuthDomain  *domain,
-			       SoupMessage     *msg);
+	char *   (*accepts)        (SoupAuthDomain *domain,
+				    SoupMessage    *msg,
+				    const char     *header);
+	char *   (*challenge)      (SoupAuthDomain *domain,
+				    SoupMessage    *msg);
+	gboolean (*check_password) (SoupAuthDomain *domain,
+				    SoupMessage    *msg,
+				    const char     *username,
+				    const char     *password);
 
 	/* Padding for future expansion */
-	void (*_libsoup_reserved1) (void);
 	void (*_libsoup_reserved2) (void);
 	void (*_libsoup_reserved3) (void);
 	void (*_libsoup_reserved4) (void);
@@ -42,8 +45,17 @@
 #define SOUP_AUTH_DOMAIN_REMOVE_PATH "remove-path"
 #define SOUP_AUTH_DOMAIN_FILTER      "filter"
 #define SOUP_AUTH_DOMAIN_FILTER_DATA "filter-data"
+#define SOUP_AUTH_DOMAIN_GENERIC_AUTH_CALLBACK "generic-auth-callback"
+#define SOUP_AUTH_DOMAIN_GENERIC_AUTH_DATA     "generic-auth-data"
 
-typedef gboolean (*SoupAuthDomainFilter) (SoupAuthDomain *, SoupMessage *, gpointer);
+typedef gboolean (*SoupAuthDomainFilter) (SoupAuthDomain *domain,
+					  SoupMessage    *msg,
+					  gpointer        user_data);
+
+typedef gboolean (*SoupAuthDomainGenericAuthCallback) (SoupAuthDomain *domain,
+						       SoupMessage    *msg,
+						       const char     *username,
+						       gpointer        user_data);
 
 GType       soup_auth_domain_get_type    (void);
 
@@ -59,6 +71,15 @@
 
 const char *soup_auth_domain_get_realm   (SoupAuthDomain       *domain);
 
+void        soup_auth_domain_set_generic_auth_callback (SoupAuthDomain *domain,
+							SoupAuthDomainGenericAuthCallback auth_callback,
+							gpointer        auth_data,
+							GDestroyNotify  dnotify);
+gboolean    soup_auth_domain_check_password (SoupAuthDomain    *domain,
+					     SoupMessage       *msg,
+					     const char        *username,
+					     const char        *password);
+
 gboolean    soup_auth_domain_covers      (SoupAuthDomain       *domain,
 					  SoupMessage          *msg);
 char       *soup_auth_domain_accepts     (SoupAuthDomain       *domain,
@@ -66,4 +87,9 @@
 void        soup_auth_domain_challenge   (SoupAuthDomain       *domain,
 					  SoupMessage          *msg);
 
+/* protected */
+gboolean    soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
+							SoupMessage    *msg,
+							const char     *username);
+
 #endif /* SOUP_AUTH_DOMAIN_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]