The current digest scheme helper protocol have great issues in how to
handle quote <"> charactes. An easy way to solve this is to switch
protocol to a protocol similar to what we already use for basic helpers
using url escaped strings

  urlescape(user) <SPACE> urlescape(realm) <NEWLINE>

Note: The reason why realm is urlescaped is to allow for future
expansions of the protocol. 

The default is still the old quoted form as helpers have not yet been
converted over. But once the helpers have been converted default should
change to urlescaped form.
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: hen...@henriknordstrom.net-20100306200338-\
#   py3969agu3ccjdeh
# target_branch: /home/henrik/SRC/squid/trunk/
# testament_sha1: b4225d56b5d7245eacec5a2406019e692aa00cce
# timestamp: 2010-03-06 21:03:58 +0100
# base_revision_id: hen...@henriknordstrom.net-20100306194302-\
#   eknq7yvpt5ygzkdz
# 
# Begin patch
=== modified file 'src/auth/digest/auth_digest.cc'
--- src/auth/digest/auth_digest.cc	2010-03-06 14:47:46 +0000
+++ src/auth/digest/auth_digest.cc	2010-03-06 19:48:42 +0000
@@ -50,6 +50,7 @@
 #include "SquidTime.h"
 /* TODO don't include this */
 #include "digestScheme.h"
+#include "rfc1738.h"
 
 /* Digest Scheme */
 
@@ -935,7 +936,9 @@
     safe_free(digestAuthRealm);
 }
 
-AuthDigestConfig::AuthDigestConfig() : authenticateChildren(20)
+AuthDigestConfig::AuthDigestConfig() :
+	authenticateChildren(20),
+	helperProtocol(DIGEST_HELPER_PROTOCOL_QUOTEDSTRING)
 {
     /* TODO: move into initialisation list */
     /* 5 minutes */
@@ -978,6 +981,17 @@
         parse_onoff(&PostWorkaround);
     } else if (strcasecmp(param_str, "utf8") == 0) {
         parse_onoff(&utf8);
+    } else if (strcasecmp(param_str, "protocol") == 0) {
+	char *token = NULL;
+	parse_eol(&token);
+	if (strcmp(token, "quoted")) {
+	    helperProtocol = DIGEST_HELPER_PROTOCOL_QUOTEDSTRING;
+	} else if (strcmp(token, "urlescaped")) {
+	    helperProtocol = DIGEST_HELPER_PROTOCOL_URLESCAPE;
+	} else {
+	    debugs(29, 0, "unrecognised digest auth helper protocol '" << token << "'");
+	}
+	safe_free(token);
     } else {
         debugs(29, 0, "unrecognised digest auth scheme parameter '" << param_str << "'");
     }
@@ -1237,10 +1251,10 @@
     }
 
     /* Sanity check of the username.
-     * " can not be allowed in usernames until * the digest helper protocol
-     * have been redone
+     * " can not be allowed in usernames when using the old quotedstring
+     * helper protocol
      */
-    if (strchr(username, '"')) {
+    if (helperProtocol == DIGEST_HELPER_PROTOCOL_QUOTEDSTRING && strchr(username, '"')) {
         debugs(29, 2, "authenticateDigestDecode: Unacceptable username '" << username << "'");
         return authDigestLogUsername(username, digest_request);
     }
@@ -1390,7 +1404,6 @@
 AuthDigestUserRequest::module_start(RH * handler, void *data)
 {
     DigestAuthenticateStateData *r = NULL;
-    char buf[8192];
     digest_user_h *digest_user;
     assert(user()->auth_type == AUTH_DIGEST);
     digest_user = dynamic_cast < digest_user_h * >(user());
@@ -1402,20 +1415,35 @@
         return;
     }
 
+
     r = cbdataAlloc(DigestAuthenticateStateData);
     r->handler = handler;
     r->data = cbdataReference(data);
     r->auth_user_request = this;
     AUTHUSERREQUESTLOCK(r->auth_user_request, "r");
+
+    const char *username = digest_user->username();
+    char utf8str[1024];
     if (digestConfig.utf8) {
-        char userstr[1024];
-        latin1_to_utf8(userstr, sizeof(userstr), digest_user->username());
-        snprintf(buf, 8192, "\"%s\":\"%s\"\n", userstr, realm);
-    } else {
-        snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username(), realm);
-    }
-
-    helperSubmit(digestauthenticators, buf, authenticateDigestHandleReply, r);
+        latin1_to_utf8(utf8str, sizeof(utf8str), username);
+	username = utf8str;
+    }
+
+    MemBuf mb;
+
+    mb.init();
+    switch(digestConfig.helperProtocol) {
+    case AuthDigestConfig::DIGEST_HELPER_PROTOCOL_QUOTEDSTRING:
+	mb.Printf("\"%s\":\"%s\"\n", username, realm);
+	break;
+    case AuthDigestConfig::DIGEST_HELPER_PROTOCOL_URLESCAPE:
+	mb.Printf("%s ", rfc1738_escape(username));
+	mb.Printf("%s\n", rfc1738_escape(realm));
+    	break;
+    }
+
+    helperSubmit(digestauthenticators, mb.buf, authenticateDigestHandleReply, r);
+    mb.clean();
 }
 
 DigestUser::DigestUser (AuthConfig *aConfig) : AuthUser (aConfig), HA1created (0)

=== modified file 'src/auth/digest/auth_digest.h'
--- src/auth/digest/auth_digest.h	2009-12-16 03:46:59 +0000
+++ src/auth/digest/auth_digest.h	2010-03-06 16:09:24 +0000
@@ -163,6 +163,10 @@
     int CheckNonceCount;
     int PostWorkaround;
     int utf8;
+    enum {
+	DIGEST_HELPER_PROTOCOL_QUOTEDSTRING,
+	DIGEST_HELPER_PROTOCOL_URLESCAPE
+    } helperProtocol;
 };
 
 typedef class AuthDigestConfig auth_digest_config;

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2010-03-06 19:43:02 +0000
+++ src/cf.data.pre	2010-03-06 20:03:38 +0000
@@ -181,13 +181,18 @@
 	=== Parameters for the digest scheme follow ===
 
 	"program" cmdline
-	Specify the command for the external authenticator.  Such
-	a program reads a line containing "username":"realm" and
+	Specify the command for the external authenticator. 
+	Such a program reads a line containing the username and realm and
 	replies with the appropriate H(A1) value hex encoded or
 	ERR if the user (or his H(A1) hash) does not exists.
 	See rfc 2616 for the definition of H(A1).
+	See the protocol directive below for a description of the different
+	request formats sent to such helpers.
 	"ERR" responses may optionally be followed by a error description
 	available as %m in the returned error page.
+	See also
+	the protocol option below for description of the request/response
+	format.
 
 	By default, the digest authentication scheme is not used unless a
 	program is specified.
@@ -226,6 +231,15 @@
 
 	auth_param digest children 20 startup=0 idle=1
 
+	protocol quoted | urlescaped
+	Specifies the helper protocol to use. In the default quoted format
+	requests are sent on the form "username":"realm" and the use of
+	usernames or realms with " characters in them is forbidden.
+	In the urlescaped protocol format request are sent on the form
+	urlescape(username) <SPACE> urlescape(realm) <NEWLINE>
+	and " may be used in the login or realm if desired.
+	In future default may change to the newer urlescaped form.
+
 	"realm" realmstring
 	Specifies the realm name which is to be reported to the
 	client for the digest proxy authentication scheme (part of

# Begin bundle
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

Reply via email to