pathoc: add socks connect

This commit is contained in:
Maximilian Hils 2015-07-03 02:48:35 +02:00
parent 4407508e0c
commit 4ef83d8c11
3 changed files with 66 additions and 2 deletions

View File

@ -11,7 +11,7 @@ import threading
import OpenSSL.crypto import OpenSSL.crypto
from netlib import tcp, http, http2, certutils, websockets from netlib import tcp, http, http2, certutils, websockets, socks
import language.http import language.http
import language.websockets import language.websockets
@ -254,6 +254,39 @@ class Pathoc(tcp.TCPClient):
) )
http.read_headers(self.rfile) http.read_headers(self.rfile)
def socks_connect(self, connect_to):
try:
client_greet = socks.ClientGreeting(socks.VERSION.SOCKS5, [socks.METHOD.NO_AUTHENTICATION_REQUIRED])
client_greet.to_file(self.wfile)
self.wfile.flush()
server_greet = socks.ServerGreeting.from_file(self.rfile)
server_greet.assert_socks5()
if server_greet.method != socks.METHOD.NO_AUTHENTICATION_REQUIRED:
raise socks.SocksError(
socks.METHOD.NO_ACCEPTABLE_METHODS,
"pathoc only supports SOCKS without authentication"
)
connect_request = socks.Message(
socks.VERSION.SOCKS5,
socks.CMD.CONNECT,
socks.ATYP.DOMAINNAME,
tcp.Address.wrap(connect_to)
)
connect_request.to_file(self.wfile)
self.wfile.flush()
connect_reply = socks.Message.from_file(self.rfile)
connect_reply.assert_socks5()
if connect_reply.msg != socks.REP.SUCCEEDED:
raise socks.SocksError(
connect_reply.msg,
"SOCKS server error"
)
except (socks.SocksError, tcp.NetLibDisconnect) as e:
raise PathocError(str(e))
def connect(self, connect_to=None, showssl=False, fp=sys.stdout): def connect(self, connect_to=None, showssl=False, fp=sys.stdout):
""" """
connect_to: A (host, port) tuple, which will be connected to with connect_to: A (host, port) tuple, which will be connected to with

View File

@ -4,7 +4,7 @@ import re
import OpenSSL import OpenSSL
from mock import Mock from mock import Mock
from netlib import tcp, http, http2 from netlib import tcp, http, http2, socks
from libpathod import pathoc, test, version, pathod, language from libpathod import pathoc, test, version, pathod, language
import tutils import tutils
@ -230,6 +230,29 @@ class TestDaemon(_TestDaemon):
) )
c.http_connect(to) c.http_connect(to)
def test_socks_connect(self):
to = ("foobar", 80)
c = pathoc.Pathoc(("127.0.0.1", self.d.port), fp=None)
c.rfile, c.wfile = tutils.treader(""), cStringIO.StringIO()
tutils.raises(pathoc.PathocError, c.socks_connect, to)
c.rfile = tutils.treader(
"\x05\xEE"
)
tutils.raises("SOCKS without authentication", c.socks_connect, ("example.com", 0xDEAD))
c.rfile = tutils.treader(
"\x05\x00" +
"\x05\xEE\x00\x03\x0bexample.com\xDE\xAD"
)
tutils.raises("SOCKS server error", c.socks_connect, ("example.com", 0xDEAD))
c.rfile = tutils.treader(
"\x05\x00" +
"\x05\x00\x00\x03\x0bexample.com\xDE\xAD"
)
c.socks_connect(("example.com", 0xDEAD))
class TestDaemonHTTP2(_TestDaemon): class TestDaemonHTTP2(_TestDaemon):
ssl = True ssl = True

View File

@ -5,8 +5,16 @@ import shutil
import cStringIO import cStringIO
from contextlib import contextmanager from contextlib import contextmanager
from libpathod import utils, test, pathoc, pathod, language from libpathod import utils, test, pathoc, pathod, language
from netlib import tcp
import requests import requests
def treader(bytes):
"""
Construct a tcp.Read object from bytes.
"""
fp = cStringIO.StringIO(bytes)
return tcp.Reader(fp)
class DaemonTests(object): class DaemonTests(object):
noweb = False noweb = False