Skip to content

Commit

Permalink
PROXY_TYPE_SOCKS5 with str user/pass raised TypeError (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
temoto authored and stinky2nine committed Sep 15, 2019
1 parent d498ee3 commit cfba120
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
.project
.pydevproject
.pytest_cache/*
.tags*
.tox
_httplib2_test_cache/*
bin
Expand Down
4 changes: 4 additions & 0 deletions python3/httplib2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,10 @@ def __init__(
proxy_headers: Additional or modified headers for the proxy connect
request.
"""
if isinstance(proxy_user, str):
proxy_user = proxy_user.encode()
if isinstance(proxy_pass, str):
proxy_pass = proxy_pass.encode()
self.proxy_type, self.proxy_host, self.proxy_port, self.proxy_rdns, self.proxy_user, self.proxy_pass, self.proxy_headers = (
proxy_type,
proxy_host,
Expand Down
22 changes: 8 additions & 14 deletions python3/httplib2/socks.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,7 @@ def __rewriteproxy(self, header):
return "\r\n".join(hdrs)

def __getauthheader(self):
username = self.__proxy[4]
password = self.__proxy[5]
if isinstance(username, str):
username = username.encode()
if isinstance(password, str):
password = password.encode()
auth = username + b":" + password
auth = self.__proxy[4] + b":" + self.__proxy[5]
return "Proxy-Authorization: Basic " + base64.b64encode(auth).decode()

def setproxy(
Expand Down Expand Up @@ -273,13 +267,13 @@ def __negotiatesocks5(self, destaddr, destport):
elif chosenauth[1:2] == chr(0x02).encode():
# Okay, we need to perform a basic username/password
# authentication.
self.sendall(
chr(0x01).encode()
+ chr(len(self.__proxy[4]))
+ self.__proxy[4]
+ chr(len(self.__proxy[5]))
+ self.__proxy[5]
)
packet = bytearray()
packet.append(0x01)
packet.append(len(self.__proxy[4]))
packet.extend(self.__proxy[4])
packet.append(len(self.__proxy[5]))
packet.extend(self.__proxy[5])
self.sendall(packet)
authstat = self.__recvall(2)
if authstat[0:1] != chr(0x01).encode():
# Bad response
Expand Down
5 changes: 3 additions & 2 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ def tick(request):
gcounter[0] += 1
keep = True
keep &= gcounter[0] < request_count
keep &= request.headers.get("connection", "").lower() != "close"
if request is not None:
keep &= request.headers.get("connection", "").lower() != "close"
return keep

def server_socket_thread(srv):
Expand All @@ -295,7 +296,7 @@ def server_socket_thread(srv):
)
except Exception as e:
# traceback.print_exc caused IOError: concurrent operation on sys.stderr.close() under setup.py test
sys.stderr.write(traceback.format_exc().encode())
print(traceback.format_exc(), file=sys.stderr)
gresult[0] = e

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Expand Down
29 changes: 27 additions & 2 deletions tests/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def test_from_url_ident():
pi = httplib2.proxy_info_from_url("http://zoidberg:fish@someproxy:99")
assert pi.proxy_host == "someproxy"
assert pi.proxy_port == 99
assert pi.proxy_user == "zoidberg"
assert pi.proxy_pass == "fish"
assert pi.proxy_user == b"zoidberg"
assert pi.proxy_pass == b"fish"


def test_from_env():
Expand Down Expand Up @@ -146,3 +146,28 @@ def test_auth_str_bytes():
)
response, _ = http.request(uri, "GET")
assert response.status == 200


def test_socks5_auth():
def proxy_conn(client, tick):
data = client.recv(64)
assert data == b"\x05\x02\x00\x02"
client.send(b"\x05\x02") # select username/password auth
data = client.recv(64)
assert data == b"\x01\x08user_str\x08pass_str"
client.send(b"\x01\x01") # deny
tick(None)

with tests.server_socket(proxy_conn) as uri:
uri_parsed = urllib.parse.urlparse(uri)
proxy_info = httplib2.ProxyInfo(
httplib2.socks.PROXY_TYPE_SOCKS5,
proxy_host=uri_parsed.hostname,
proxy_port=uri_parsed.port,
proxy_rdns=True,
proxy_user=u"user_str",
proxy_pass=u"pass_str",
)
http = httplib2.Http(proxy_info=proxy_info)
with tests.assert_raises(httplib2.socks.Socks5AuthError):
http.request(uri, "GET")

0 comments on commit cfba120

Please sign in to comment.