mirror of
https://github.com/python/cpython.git
synced 2025-08-18 15:51:23 +00:00
- Issue #13642: Unquote before b64encoding user:password during Basic
Authentication. Patch contributed by Joonas Kuorilehto and Michele Orrù.
This commit is contained in:
parent
a0ff91cac0
commit
bcd833f30f
3 changed files with 60 additions and 8 deletions
|
@ -3,13 +3,16 @@
|
||||||
import urllib
|
import urllib
|
||||||
import httplib
|
import httplib
|
||||||
import unittest
|
import unittest
|
||||||
from test import test_support
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import mimetools
|
import mimetools
|
||||||
import tempfile
|
import tempfile
|
||||||
import StringIO
|
import StringIO
|
||||||
|
|
||||||
|
from test import test_support
|
||||||
|
from base64 import b64encode
|
||||||
|
|
||||||
|
|
||||||
def hexescape(char):
|
def hexescape(char):
|
||||||
"""Escape char as RFC 2396 specifies"""
|
"""Escape char as RFC 2396 specifies"""
|
||||||
hex_repr = hex(ord(char))[2:].upper()
|
hex_repr = hex(ord(char))[2:].upper()
|
||||||
|
@ -22,8 +25,9 @@ class FakeHTTPMixin(object):
|
||||||
def fakehttp(self, fakedata):
|
def fakehttp(self, fakedata):
|
||||||
class FakeSocket(StringIO.StringIO):
|
class FakeSocket(StringIO.StringIO):
|
||||||
|
|
||||||
def sendall(self, str):
|
def sendall(self, data):
|
||||||
pass
|
FakeHTTPConnection.buf = data
|
||||||
|
|
||||||
def makefile(self, *args, **kwds):
|
def makefile(self, *args, **kwds):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -38,9 +42,15 @@ class FakeHTTPMixin(object):
|
||||||
return StringIO.StringIO.readline(self, length)
|
return StringIO.StringIO.readline(self, length)
|
||||||
|
|
||||||
class FakeHTTPConnection(httplib.HTTPConnection):
|
class FakeHTTPConnection(httplib.HTTPConnection):
|
||||||
|
|
||||||
|
# buffer to store data for verification in urlopen tests.
|
||||||
|
buf = ""
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
self.sock = FakeSocket(fakedata)
|
self.sock = FakeSocket(fakedata)
|
||||||
|
|
||||||
assert httplib.HTTP._connection_class == httplib.HTTPConnection
|
assert httplib.HTTP._connection_class == httplib.HTTPConnection
|
||||||
|
|
||||||
httplib.HTTP._connection_class = FakeHTTPConnection
|
httplib.HTTP._connection_class = FakeHTTPConnection
|
||||||
|
|
||||||
def unfakehttp(self):
|
def unfakehttp(self):
|
||||||
|
@ -209,6 +219,41 @@ Content-Type: text/html; charset=iso-8859-1
|
||||||
finally:
|
finally:
|
||||||
self.unfakehttp()
|
self.unfakehttp()
|
||||||
|
|
||||||
|
def test_userpass_inurl(self):
|
||||||
|
self.fakehttp('Hello!')
|
||||||
|
try:
|
||||||
|
fakehttp_wrapper = httplib.HTTP._connection_class
|
||||||
|
fp = urllib.urlopen("http://user:pass@python.org/")
|
||||||
|
authorization = ("Authorization: Basic %s\r\n" %
|
||||||
|
b64encode('user:pass'))
|
||||||
|
# The authorization header must be in place
|
||||||
|
self.assertIn(authorization, fakehttp_wrapper.buf)
|
||||||
|
self.assertEqual(fp.readline(), "Hello!")
|
||||||
|
self.assertEqual(fp.readline(), "")
|
||||||
|
self.assertEqual(fp.geturl(), 'http://user:pass@python.org/')
|
||||||
|
self.assertEqual(fp.getcode(), 200)
|
||||||
|
finally:
|
||||||
|
self.unfakehttp()
|
||||||
|
|
||||||
|
def test_userpass_with_spaces_inurl(self):
|
||||||
|
self.fakehttp('Hello!')
|
||||||
|
try:
|
||||||
|
url = "http://a b:c d@python.org/"
|
||||||
|
fakehttp_wrapper = httplib.HTTP._connection_class
|
||||||
|
authorization = ("Authorization: Basic %s\r\n" %
|
||||||
|
b64encode('a b:c d'))
|
||||||
|
fp = urllib.urlopen(url)
|
||||||
|
# The authorization header must be in place
|
||||||
|
self.assertIn(authorization, fakehttp_wrapper.buf)
|
||||||
|
self.assertEqual(fp.readline(), "Hello!")
|
||||||
|
self.assertEqual(fp.readline(), "")
|
||||||
|
# the spaces are quoted in URL so no match
|
||||||
|
self.assertNotEqual(fp.geturl(), url)
|
||||||
|
self.assertEqual(fp.getcode(), 200)
|
||||||
|
finally:
|
||||||
|
self.unfakehttp()
|
||||||
|
|
||||||
|
|
||||||
class urlretrieve_FileTests(unittest.TestCase):
|
class urlretrieve_FileTests(unittest.TestCase):
|
||||||
"""Test urllib.urlretrieve() on local files"""
|
"""Test urllib.urlretrieve() on local files"""
|
||||||
|
|
||||||
|
@ -716,6 +761,9 @@ class Utility_Tests(unittest.TestCase):
|
||||||
self.assertEqual(('user', 'a\fb'),urllib.splitpasswd('user:a\fb'))
|
self.assertEqual(('user', 'a\fb'),urllib.splitpasswd('user:a\fb'))
|
||||||
self.assertEqual(('user', 'a\vb'),urllib.splitpasswd('user:a\vb'))
|
self.assertEqual(('user', 'a\vb'),urllib.splitpasswd('user:a\vb'))
|
||||||
self.assertEqual(('user', 'a:b'),urllib.splitpasswd('user:a:b'))
|
self.assertEqual(('user', 'a:b'),urllib.splitpasswd('user:a:b'))
|
||||||
|
self.assertEqual(('user', 'a b'),urllib.splitpasswd('user:a b'))
|
||||||
|
self.assertEqual(('user 2', 'ab'),urllib.splitpasswd('user 2:ab'))
|
||||||
|
self.assertEqual(('user+1', 'a+b'),urllib.splitpasswd('user+1:a+b'))
|
||||||
|
|
||||||
|
|
||||||
class URLopener_Tests(unittest.TestCase):
|
class URLopener_Tests(unittest.TestCase):
|
||||||
|
|
|
@ -27,6 +27,8 @@ import socket
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
|
import base64
|
||||||
|
|
||||||
from urlparse import urljoin as basejoin
|
from urlparse import urljoin as basejoin
|
||||||
|
|
||||||
__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
|
__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve",
|
||||||
|
@ -318,13 +320,13 @@ class URLopener:
|
||||||
if not host: raise IOError, ('http error', 'no host given')
|
if not host: raise IOError, ('http error', 'no host given')
|
||||||
|
|
||||||
if proxy_passwd:
|
if proxy_passwd:
|
||||||
import base64
|
proxy_passwd = unquote(proxy_passwd)
|
||||||
proxy_auth = base64.b64encode(proxy_passwd).strip()
|
proxy_auth = base64.b64encode(proxy_passwd).strip()
|
||||||
else:
|
else:
|
||||||
proxy_auth = None
|
proxy_auth = None
|
||||||
|
|
||||||
if user_passwd:
|
if user_passwd:
|
||||||
import base64
|
user_passwd = unquote(user_passwd)
|
||||||
auth = base64.b64encode(user_passwd).strip()
|
auth = base64.b64encode(user_passwd).strip()
|
||||||
else:
|
else:
|
||||||
auth = None
|
auth = None
|
||||||
|
@ -408,12 +410,12 @@ class URLopener:
|
||||||
#print "proxy via https:", host, selector
|
#print "proxy via https:", host, selector
|
||||||
if not host: raise IOError, ('https error', 'no host given')
|
if not host: raise IOError, ('https error', 'no host given')
|
||||||
if proxy_passwd:
|
if proxy_passwd:
|
||||||
import base64
|
proxy_passwd = unquote(proxy_passwd)
|
||||||
proxy_auth = base64.b64encode(proxy_passwd).strip()
|
proxy_auth = base64.b64encode(proxy_passwd).strip()
|
||||||
else:
|
else:
|
||||||
proxy_auth = None
|
proxy_auth = None
|
||||||
if user_passwd:
|
if user_passwd:
|
||||||
import base64
|
user_passwd = unquote(user_passwd)
|
||||||
auth = base64.b64encode(user_passwd).strip()
|
auth = base64.b64encode(user_passwd).strip()
|
||||||
else:
|
else:
|
||||||
auth = None
|
auth = None
|
||||||
|
@ -589,7 +591,6 @@ class URLopener:
|
||||||
time.gmtime(time.time())))
|
time.gmtime(time.time())))
|
||||||
msg.append('Content-type: %s' % type)
|
msg.append('Content-type: %s' % type)
|
||||||
if encoding == 'base64':
|
if encoding == 'base64':
|
||||||
import base64
|
|
||||||
data = base64.decodestring(data)
|
data = base64.decodestring(data)
|
||||||
else:
|
else:
|
||||||
data = unquote(data)
|
data = unquote(data)
|
||||||
|
|
|
@ -89,6 +89,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13642: Unquote before b64encoding user:password during Basic
|
||||||
|
Authentication. Patch contributed by Joonas Kuorilehto and Michele Orrù.
|
||||||
|
|
||||||
- Issue #13636: Weak ciphers are now disabled by default in the ssl module
|
- Issue #13636: Weak ciphers are now disabled by default in the ssl module
|
||||||
(except when SSLv2 is explicitly asked for).
|
(except when SSLv2 is explicitly asked for).
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue