]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
auth_param basic&digest utf8 on|of
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Mon, 7 Jul 2008 11:53:28 +0000 (13:53 +0200)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Mon, 7 Jul 2008 11:53:28 +0000 (13:53 +0200)
new utf8 auth_param option to enable UTF-8 translation of the requests
sent to auth helpers. HTTP uses iso-8859-1 in authentication credentials,
but many authentication backends expects UTF-8 as charset.

Note: This does NOT solve the bigger HTTP problem of authentication using
characters outside iso-8859-1, only simlplifies things a bit by allowing
helpers to operate in UTF-8 even when HTTP operates in iso-8859-1.

An alternative would be to add the translation to each helper.

include/util.h
lib/Makefile.am
lib/charset.c [new file with mode: 0644]
src/auth/basic/auth_basic.cc
src/auth/basic/auth_basic.h
src/auth/digest/auth_digest.cc
src/auth/digest/auth_digest.h

index ea36180a9e3b6baa8f9ac63c852ddbf558acb382..2bb0a13d1f7a08ae9c686e96908d6ed90445cb69 100644 (file)
@@ -101,6 +101,9 @@ SQUIDCEXTERN char *rfc1738_escape_unescaped(const char *);
 SQUIDCEXTERN char *rfc1738_escape_part(const char *);
 SQUIDCEXTERN void rfc1738_unescape(char *);
 
+/* charset.c */
+SQUIDCEXTERN char *latin1_to_utf8(char *out, size_t size, const char *in);
+
 /* html.c */
 SQUIDCEXTERN char *html_quote(const char *);
 
index 4781a6d1fc9ad2c5b691a06a67d921b7e1a9dc79..fe2ef373254d4ff3319d3e13ecdbff6e799cf94f 100755 (executable)
@@ -68,6 +68,7 @@ EXTRA_libmiscutil_a_SOURCES = \
 libmiscutil_a_SOURCES = \
        MemPool.cc \
        base64.c \
+       charset.c \
        getfullhostname.c \
        hash.c \
        heap.c \
diff --git a/lib/charset.c b/lib/charset.c
new file mode 100644 (file)
index 0000000..bc0223a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * $Id: charset.c,v 1.1 2008/07/07 11:04:47 hno Exp $
+ *
+ * DEBUG: 
+ * AUTHOR: Henrik Nordstrom <henrik@henriknordstrom.net>
+ * 
+ * Copyright (C) 2008 Henrik Nordstrom
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "config.h"
+#include "util.h"
+
+/* Convert ISO-LATIN-1 to UTF-8
+ */
+char *
+latin1_to_utf8(char *out, size_t size, const char *in)
+{
+    unsigned char *p;
+    for (p = (unsigned char *)out; *in && size > 2; in++) {
+       unsigned char ch = (unsigned char)*in;
+       if (ch < 0x80) {
+           *p++ = ch;
+           size--;
+       } else {
+           *p++ = (ch >> 6) | 0xc0;
+           size--;
+           *p++ = (ch & 0x3f) | 0x80;
+           size--;
+       }
+    }
+    *p++ = '\0';
+    if (*in)
+       return NULL;
+    return out;
+}
+
+
index 60c773a8433f1792f8ee95e54911518d5f3dfcc2..292fbc612f2501e575a7b44f937b29466cc36d8b 100644 (file)
@@ -342,6 +342,8 @@ AuthBasicConfig::parse(AuthConfig * scheme, int n_configured, char *param_str)
         parse_time_t(&credentialsTTL);
     } else if (strcasecmp(param_str, "casesensitive") == 0) {
         parse_onoff(&casesensitive);
+    } else if (strcasecmp(param_str, "utf8") == 0) {
+        parse_onoff(&utf8);
     } else {
         debugs(29, DBG_CRITICAL, HERE << "unrecognised basic auth scheme parameter '" << param_str << "'");
     }
@@ -680,8 +682,15 @@ BasicUser::submitRequest(AuthUserRequest * auth_user_request, RH * handler, void
     r->handler = handler;
     r->data = cbdataReference(data);
     r->auth_user_request = auth_user_request;
-    xstrncpy(user, rfc1738_escape(username()), sizeof(user));
-    xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass));
+    if (basicConfig.utf8) {
+       latin1_to_utf8(user, sizeof(user), username());
+       latin1_to_utf8(pass, sizeof(pass), passwd);
+       xstrncpy(user, rfc1738_escape(user), sizeof(user));
+       xstrncpy(pass, rfc1738_escape(pass), sizeof(pass));
+    } else {
+       xstrncpy(user, rfc1738_escape(username()), sizeof(user));
+       xstrncpy(pass, rfc1738_escape(passwd), sizeof(pass));
+    }
     snprintf(buf, sizeof(buf), "%s %s\n", user, pass);
     helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r);
 }
index c1d335d24de04db0a0eab702f6e14348887ae85c..db40efbe4c902c8e50efbc24ba90fbff6691020c 100644 (file)
@@ -132,6 +132,7 @@ public:
     wordlist *authenticate;
     time_t credentialsTTL;
     int casesensitive;
+    int utf8;
 };
 
 #endif
index 32f6dbe25f67fa0bd404947b52aa072a80c63c69..d39a11d885a0794557700ebf888010240a68fc99 100644 (file)
@@ -948,6 +948,8 @@ AuthDigestConfig::parse(AuthConfig * scheme, int n_configured, char *param_str)
         parse_onoff(&CheckNonceCount);
     } else if (strcasecmp(param_str, "post_workaround") == 0) {
         parse_onoff(&PostWorkaround);
+    } else if (strcasecmp(param_str, "utf8") == 0) {
+        parse_onoff(&utf8);
     } else {
         debugs(29, 0, "unrecognised digest auth scheme parameter '" << param_str << "'");
     }
@@ -1363,7 +1365,13 @@ AuthDigestUserRequest::module_start(RH * handler, void *data)
     r->data = cbdataReference(data);
     r->auth_user_request = this;
     AUTHUSERREQUESTLOCK(r->auth_user_request, "r");
-    snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username(), realm);
+    if (digestConfig.utf8) {
+       char user[1024];
+       latin1_to_utf8(user, sizeof(user), digest_user->username());
+       snprintf(buf, 8192, "\"%s\":\"%s\"\n", user, realm);
+    } else {
+       snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username(), realm);
+    }
 
     helperSubmit(digestauthenticators, buf, authenticateDigestHandleReply, r);
 }
index 73b05086f29f781f5f149b24f9ef29e77f075074..c39995f77943fcd156e1656d23c1775e958e3d4d 100644 (file)
@@ -164,6 +164,7 @@ public:
     int NonceStrictness;
     int CheckNonceCount;
     int PostWorkaround;
+    int utf8;
 };
 
 typedef class AuthDigestConfig auth_digest_config;