1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

Fix possible authentication problem with turkish locale

The test server now treats authentication schemes case-independent.
This commit is contained in:
Tim Rühsen 2014-11-17 17:16:54 +01:00
parent db621341a4
commit 94b8458af1
6 changed files with 43 additions and 24 deletions

View File

@ -1,3 +1,7 @@
2014-11-17 Tim Ruehsen <tim.ruehsen@gmx.de>
* bootstrap.conf (gnulib_modules): Add module c-strcase
2014-11-16 Darshit Shah <darnir@gmail.com> 2014-11-16 Darshit Shah <darnir@gmail.com>
* po/stamp-po: Remove autogenerated file from checked out sources * po/stamp-po: Remove autogenerated file from checked out sources

View File

@ -31,6 +31,7 @@ announce-gen
base32 base32
bind bind
c-ctype c-ctype
c-strcase
clock-time clock-time
close close
connect connect

View File

@ -1,3 +1,8 @@
2014-11-17 Tim Ruehsen <tim.ruehsen@gmx.de>
* http.c: use c_strncasecmp() in BEGINS_WITH macro
and in STARTS macro
2014-11-17 Tim Ruehsen <tim.ruehsen@gmx.de> 2014-11-17 Tim Ruehsen <tim.ruehsen@gmx.de>
* main.c: code cleanup for redirect_output_signal() * main.c: code cleanup for redirect_output_signal()

View File

@ -59,6 +59,7 @@ as that of the covered work. */
#include "convert.h" #include "convert.h"
#include "spider.h" #include "spider.h"
#include "warc.h" #include "warc.h"
#include "c-strcase.h"
#ifdef TESTING #ifdef TESTING
#include "test.h" #include "test.h"
@ -1631,7 +1632,7 @@ read_response_body (struct http_stat *hs, int sock, FILE *fp, wgint contlen,
} }
#define BEGINS_WITH(line, string_constant) \ #define BEGINS_WITH(line, string_constant) \
(!strncasecmp (line, string_constant, sizeof (string_constant) - 1) \ (!c_strncasecmp (line, string_constant, sizeof (string_constant) - 1) \
&& (c_isspace (line[sizeof (string_constant) - 1]) \ && (c_isspace (line[sizeof (string_constant) - 1]) \
|| !line[sizeof (string_constant) - 1])) || !line[sizeof (string_constant) - 1]))
@ -3958,7 +3959,7 @@ digest_authentication_encode (const char *au, const char *user,
#define STARTS(literal, b, e) \ #define STARTS(literal, b, e) \
((e > b) \ ((e > b) \
&& ((size_t) ((e) - (b))) >= STRSIZE (literal) \ && ((size_t) ((e) - (b))) >= STRSIZE (literal) \
&& 0 == strncasecmp (b, literal, STRSIZE (literal)) \ && 0 == c_strncasecmp (b, literal, STRSIZE (literal)) \
&& ((size_t) ((e) - (b)) == STRSIZE (literal) \ && ((size_t) ((e) - (b)) == STRSIZE (literal) \
|| c_isspace (b[STRSIZE (literal)]))) || c_isspace (b[STRSIZE (literal)])))

View File

@ -1,3 +1,8 @@
2014-11-17 Tim Ruehsen <tim.ruehsen@gmx.de>
* server/http/http_server.py: allow case-insensitive auth-type,
send BasIc and DIgest to provoke Wget failures with turkish locales
2014-11-15 Darshit Shah <darnir@gmail.com> 2014-11-15 Darshit Shah <darnir@gmail.com>
* certs/README: Remove trailing whitespaces * certs/README: Remove trailing whitespaces

View File

@ -205,34 +205,37 @@ class _Handler (BaseHTTPRequestHandler):
return string.decode ('utf-8') return string.decode ('utf-8')
def send_challenge (self, auth_type): def send_challenge (self, auth_type):
if auth_type == "Both": auth_type = auth_type.lower()
self.send_challenge ("Digest") if auth_type == "both":
self.send_challenge ("Basic") self.send_challenge ("digest")
self.send_challenge ("basic")
return return
if auth_type == "Basic": if auth_type == "basic":
challenge_str = 'Basic realm="Wget-Test"' challenge_str = 'BasIc realm="Wget-Test"'
elif auth_type == "Digest" or auth_type == "Both_inline": elif auth_type == "digest" or auth_type == "both_inline":
self.nonce = md5 (str (random ()).encode ('utf-8')).hexdigest() self.nonce = md5 (str (random ()).encode ('utf-8')).hexdigest()
self.opaque = md5 (str (random ()).encode ('utf-8')).hexdigest() self.opaque = md5 (str (random ()).encode ('utf-8')).hexdigest()
challenge_str = 'Digest realm="Test", nonce="%s", opaque="%s"' % ( # 'DIgest' to provoke a Wget failure with turkish locales
challenge_str = 'DIgest realm="Test", nonce="%s", opaque="%s"' % (
self.nonce, self.nonce,
self.opaque) self.opaque)
challenge_str += ', qop="auth"' challenge_str += ', qop="auth"'
if auth_type == "Both_inline": if auth_type == "both_inline":
challenge_str = 'Basic realm="Wget-Test", ' + challenge_str # 'BasIc' to provoke a Wget failure with turkish locales
challenge_str = 'BasIc realm="Wget-Test", ' + challenge_str
self.send_header ("WWW-Authenticate", challenge_str) self.send_header ("WWW-Authenticate", challenge_str)
def authorize_Basic (self, auth_header, auth_rule): def authorize_basic (self, auth_header, auth_rule):
if auth_header is None or auth_header.split(' ')[0] != 'Basic': if auth_header is None or auth_header.split(' ')[0].lower() != 'basic':
return False return False
else: else:
self.user = auth_rule.auth_user self.user = auth_rule.auth_user
self.passw = auth_rule.auth_pass self.passw = auth_rule.auth_pass
auth_str = "Basic " + self.base64 (self.user + ":" + self.passw) auth_str = "basic " + self.base64 (self.user + ":" + self.passw)
return True if auth_str == auth_header else False return True if auth_str.lower() == auth_header.lower() else False
def parse_auth_header (self, auth_header): def parse_auth_header (self, auth_header):
n = len("Digest ") n = len("digest ")
auth_header = auth_header[n:].strip() auth_header = auth_header[n:].strip()
items = auth_header.split(", ") items = auth_header.split(", ")
keyvals = [i.split("=", 1) for i in items] keyvals = [i.split("=", 1) for i in items]
@ -264,8 +267,8 @@ class _Handler (BaseHTTPRequestHandler):
return True if resp == params['response'] else False return True if resp == params['response'] else False
def authorize_Digest (self, auth_header, auth_rule): def authorize_digest (self, auth_header, auth_rule):
if auth_header is None or auth_header.split(' ')[0] != 'Digest': if auth_header is None or auth_header.split(' ')[0].lower() != 'digest':
return False return False
else: else:
self.user = auth_rule.auth_user self.user = auth_rule.auth_user
@ -284,10 +287,10 @@ class _Handler (BaseHTTPRequestHandler):
pass_auth = False pass_auth = False
return pass_auth return pass_auth
def authorize_Both (self, auth_header, auth_rule): def authorize_both (self, auth_header, auth_rule):
return False return False
def authorize_Both_inline (self, auth_header, auth_rule): def authorize_both_inline (self, auth_header, auth_rule):
return False return False
def Authentication (self, auth_rule): def Authentication (self, auth_rule):
@ -302,16 +305,16 @@ class _Handler (BaseHTTPRequestHandler):
def handle_auth (self, auth_rule): def handle_auth (self, auth_rule):
is_auth = True is_auth = True
auth_header = self.headers.get ("Authorization") auth_header = self.headers.get ("Authorization")
required_auth = auth_rule.auth_type required_auth = auth_rule.auth_type.lower()
if required_auth == "Both" or required_auth == "Both_inline": if required_auth == "both" or required_auth == "both_inline":
auth_type = auth_header.split(' ')[0] if auth_header else required_auth auth_type = auth_header.split(' ')[0].lower() if auth_header else required_auth
else: else:
auth_type = required_auth auth_type = required_auth
try: try:
assert hasattr (self, "authorize_" + auth_type) assert hasattr (self, "authorize_" + auth_type)
is_auth = getattr (self, "authorize_" + auth_type) (auth_header, auth_rule) is_auth = getattr (self, "authorize_" + auth_type) (auth_header, auth_rule)
except AssertionError: except AssertionError:
raise ServerError ("Authentication Mechanism " + auth_rule + " not supported") raise ServerError ("Authentication Mechanism " + auth_type + " not supported")
except AttributeError as ae: except AttributeError as ae:
raise ServerError (ae.__str__()) raise ServerError (ae.__str__())
if is_auth is False: if is_auth is False: