From: Henrik Nordstrom Date: Mon, 7 Jul 2008 11:53:28 +0000 (+0200) Subject: auth_param basic&digest utf8 on|of X-Git-Tag: SQUID_3_1_0_1~49^2~164 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f741d2f67e30e79a7cac424ba0f33bea148fa034;p=thirdparty%2Fsquid.git auth_param basic&digest utf8 on|of 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. --- diff --git a/include/util.h b/include/util.h index ea36180a9e..2bb0a13d1f 100644 --- a/include/util.h +++ b/include/util.h @@ -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 *); diff --git a/lib/Makefile.am b/lib/Makefile.am index 4781a6d1fc..fe2ef37325 100755 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -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 index 0000000000..bc0223a460 --- /dev/null +++ b/lib/charset.c @@ -0,0 +1,55 @@ +/* + * $Id: charset.c,v 1.1 2008/07/07 11:04:47 hno Exp $ + * + * DEBUG: + * AUTHOR: Henrik Nordstrom + * + * 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; +} + + diff --git a/src/auth/basic/auth_basic.cc b/src/auth/basic/auth_basic.cc index 60c773a843..292fbc612f 100644 --- a/src/auth/basic/auth_basic.cc +++ b/src/auth/basic/auth_basic.cc @@ -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); } diff --git a/src/auth/basic/auth_basic.h b/src/auth/basic/auth_basic.h index c1d335d24d..db40efbe4c 100644 --- a/src/auth/basic/auth_basic.h +++ b/src/auth/basic/auth_basic.h @@ -132,6 +132,7 @@ public: wordlist *authenticate; time_t credentialsTTL; int casesensitive; + int utf8; }; #endif diff --git a/src/auth/digest/auth_digest.cc b/src/auth/digest/auth_digest.cc index 32f6dbe25f..d39a11d885 100644 --- a/src/auth/digest/auth_digest.cc +++ b/src/auth/digest/auth_digest.cc @@ -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); } diff --git a/src/auth/digest/auth_digest.h b/src/auth/digest/auth_digest.h index 73b05086f2..c39995f779 100644 --- a/src/auth/digest/auth_digest.h +++ b/src/auth/digest/auth_digest.h @@ -164,6 +164,7 @@ public: int NonceStrictness; int CheckNonceCount; int PostWorkaround; + int utf8; }; typedef class AuthDigestConfig auth_digest_config;