[Pkg-privacy-commits] [obfsproxy] 274/353: Add suport for connecting via SOCKS4(a)/SOCKS5 using txsocksx
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 13:02:10 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository obfsproxy.
commit 10cd8870adde32e7f2fa9a2376d8706522f33f88
Author: Yawning Angel <yawning at schwanenlied.me>
Date: Wed Mar 19 09:45:50 2014 +0000
Add suport for connecting via SOCKS4(a)/SOCKS5 using txsocksx
Patch originally by Arturo Filasto, with changes by Yawning Angel. This
patch depends on pyptlib modifications as it also supports using the
managed TOR_PT_PROXY enviornment variable.
WARNING: Attempting to use a http proxy will break mysteriously as the
connect routines are just stubbed out.
---
ChangeLog | 5 ++++
obfsproxy/common/settings.py | 5 ++++
obfsproxy/managed/client.py | 9 +++++++
obfsproxy/network/network.py | 56 +++++++++++++++++++++++++++++++++++++++++++-
obfsproxy/network/socks.py | 20 ++++++++++++++--
obfsproxy/pyobfsproxy.py | 11 +++++++++
setup.py | 5 ++--
7 files changed, 106 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0ef5910..da37aca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Changes in version 0.2.8 - UNRELEASED
+ - Support connecting over SOCKS4(a) and SOCKS5. Based on the patch by
+ Arturo Filasto with changes by Yawning Angel. Fixes #8956.
+
+
Changes in version 0.2.7 - 2014-03-15
- Support SOCKS5 instead of SOCKS4. Patch by Yawning Angel. Fixes #9221.
- Fix a scramblesuit bug that makes bridges reject a session
diff --git a/obfsproxy/common/settings.py b/obfsproxy/common/settings.py
new file mode 100644
index 0000000..4f58ce8
--- /dev/null
+++ b/obfsproxy/common/settings.py
@@ -0,0 +1,5 @@
+class Config(object):
+ def __init__(self):
+ self.proxy = None
+
+config = Config()
diff --git a/obfsproxy/managed/client.py b/obfsproxy/managed/client.py
index bce5463..ffcdd49 100644
--- a/obfsproxy/managed/client.py
+++ b/obfsproxy/managed/client.py
@@ -6,6 +6,7 @@ from twisted.internet import reactor, error
import obfsproxy.network.launch_transport as launch_transport
import obfsproxy.transports.transports as transports
import obfsproxy.common.log as logging
+import obfsproxy.common.settings as settings
import obfsproxy.common.transport_config as transport_config
from pyptlib.client import ClientTransportPlugin
@@ -29,6 +30,14 @@ def do_managed_client():
log.debug("pyptlib gave us the following data:\n'%s'", pprint.pformat(ptclient.getDebugData()))
+ # Apply the proxy settings if any
+ proxy = ptclient.config.getProxy()
+ if proxy:
+ if settings.config.proxy:
+ log.warning("Proxy specified via commandline and by managed-proxy protocol, using manage-proxy's")
+ settings.config.proxy = proxy
+ ptclient.reportProxySuccess()
+
for transport in ptclient.getTransports():
# Will hold configuration parameters for the pluggable transport module.
diff --git a/obfsproxy/network/network.py b/obfsproxy/network/network.py
index 4a8b641..3a8d124 100644
--- a/obfsproxy/network/network.py
+++ b/obfsproxy/network/network.py
@@ -1,6 +1,9 @@
from twisted.internet import reactor
+from twisted.internet.endpoints import HostnameEndpoint
from twisted.internet.protocol import Protocol, Factory
+from txsocksx.client import SOCKS4ClientEndpoint, SOCKS5ClientEndpoint
+
import obfsproxy.common.log as logging
import obfsproxy.common.heartbeat as heartbeat
@@ -367,7 +370,58 @@ class StaticDestinationServerFactory(Factory):
# XXX instantiates a new factory for each client
clientFactory = StaticDestinationClientFactory(circuit, self.mode)
- reactor.connectTCP(self.remote_host, self.remote_port, clientFactory)
+
+ if settings.config.proxy:
+ create_proxy_client(self.remote_host, self.remote_port,
+ settings.config.proxy,
+ klass_instance=clientFactory)
+ else:
+ reactor.connectTCP(self.remote_host, self.remote_port, clientFactory)
return StaticDestinationProtocol(circuit, self.mode, addr)
+def create_proxy_client(host, port, proxy_spec, klass=None, klass_args=None):
+ """
+ host:
+ the host of the final destination
+ port:
+ the port number of the final destination
+ proxy_spec:
+ the address of the proxy server as a urlparse.SplitResult
+ klass:
+ is either a class or instance
+ klass_args:
+ if specified klass will be treated as a class and will be passed to the class constructor
+
+ Returns a deferred that will fire when the connection to the SOCKS server has been established.
+ """
+
+ log.debug("Connecting via %s proxy %s:%d" % (proxy_spec.scheme, log.safe_addr_str(proxy_spec.hostname), proxy_spec.port))
+
+ if proxy_spec.scheme in ["socks4a", "socks5"]:
+ TCPPoint = HostnameEndpoint(reactor, proxy_spec.hostname, proxy_spec.port)
+ username = proxy_spec.username
+ password = proxy_spec.password
+ if proxy_spec.scheme == "socks4a":
+ if username:
+ assert(password == None)
+ SOCKSPoint = SOCKS4ClientEndpoint(host, port, TCPPoint, user=username)
+ else:
+ SOCKSPoint = SOCKS4ClientEndpoint(host, port, TCPPoint)
+ elif proxy_spec.scheme == "socks5":
+ if username and password:
+ SOCKSPoint = SOCKS5ClientEndpoint(host, port, TCPPoint,
+ methods={'login': (username, password)})
+ else:
+ assert(username == None and password == None)
+ SOCKSPoint = SOCKS5ClientEndpoint(host, port, TCPPoint)
+ if klass_args:
+ d = SOCKSPoint.connect(klass(klass_args))
+ else:
+ d = SOCKSPoint.connect(klass)
+ return d
+ elif proxy_spec.scheme == "http":
+ pass
+ else:
+ # Should *NEVER* happen
+ raise RuntimeError("Invalid proxy scheme %s" % proxy_spec.scheme)
diff --git a/obfsproxy/network/socks.py b/obfsproxy/network/socks.py
index 842e4a5..16b93bf 100644
--- a/obfsproxy/network/socks.py
+++ b/obfsproxy/network/socks.py
@@ -6,6 +6,7 @@ import obfsproxy.common.log as logging
import obfsproxy.network.network as network
import obfsproxy.network.socks5 as socks5
import obfsproxy.transports.base as base
+from obfsproxy.common import settings
log = logging.get_obfslogger()
@@ -65,6 +66,16 @@ class OBFSSOCKSv5Outgoing(socks5.SOCKSv5Outgoing, network.GenericProtocol):
self.buffer.write(data)
self.circuit.dataReceived(self.buffer, self)
+class OBFSSOCKSv5OutgoingFactory(protocol.Factory):
+ """
+ A OBFSSOCKSv5OutgoingFactory, used only when connecting via a proxy
+ """
+
+ def __init__(self, socksProtocol):
+ self.socks = socksProtocol
+
+ def buildProtocol(self, addr):
+ return OBFSSOCKSv5Outgoing(self.socks)
class OBFSSOCKSv5Protocol(socks5.SOCKSv5Protocol, network.GenericProtocol):
"""
@@ -130,10 +141,15 @@ class OBFSSOCKSv5Protocol(socks5.SOCKSv5Protocol, network.GenericProtocol):
"""
Instantiate the outgoing connection.
- This is overriden so that our sub-classed SOCKSv5Outgoing gets created.
+ This is overriden so that our sub-classed SOCKSv5Outgoing gets created,
+ and a proxy is optionally used for the outgoing connection.
"""
- return protocol.ClientCreator(reactor, OBFSSOCKSv5Outgoing, self).connectTCP(addr, port)
+ if settings.config.proxy:
+ instance = OBFSSOCKSv5OutgoingFactory(self)
+ return network.create_proxy_client(addr, port, settings.config.proxy, klass=instance)
+ else:
+ return protocol.ClientCreator(reactor, OBFSSOCKSv5Outgoing, self).connectTCP(addr, port)
def set_up_circuit(self, otherConn):
self.circuit.setDownstreamConnection(otherConn)
diff --git a/obfsproxy/pyobfsproxy.py b/obfsproxy/pyobfsproxy.py
index 4227c2f..ce813b0 100755
--- a/obfsproxy/pyobfsproxy.py
+++ b/obfsproxy/pyobfsproxy.py
@@ -18,8 +18,10 @@ import obfsproxy.common.transport_config as transport_config
import obfsproxy.managed.server as managed_server
import obfsproxy.managed.client as managed_client
from obfsproxy import __version__
+from obfsproxy.common import settings
from pyptlib.config import checkClientMode
+from pyptlib.client_config import parseProxyURI
from twisted.internet import task # for LoopingCall
@@ -47,6 +49,9 @@ def set_up_cli_parsing():
parser.add_argument('--data-dir', help='where persistent information should be stored.',
default=None)
+ parser.add_argument('--proxy', action='store', dest='proxy',
+ help='Outgoing proxy (<proxy_type>://[<user_name>][:<password>][@]<ip>:<port>)')
+
# Managed mode is a subparser for now because there are no
# optional subparsers: bugs.python.org/issue9253
subparsers.add_parser("managed", help="managed mode")
@@ -104,6 +109,12 @@ def consider_cli_args(args):
log.disable_logs()
if args.no_safe_logging:
log.set_no_safe_logging()
+ if args.proxy:
+ try:
+ settings.config.proxy = parseProxyURI(args.proxy)
+ except Exception as e:
+ log.error("Failed to parse proxy specifier: %s" % e)
+ sys.exit(1)
# validate:
if (args.name == 'managed') and (not args.log_file) and (args.log_min_severity):
diff --git a/setup.py b/setup.py
index d2d241a..7017e75 100644
--- a/setup.py
+++ b/setup.py
@@ -33,7 +33,8 @@ setup(
'PyCrypto',
'Twisted',
'argparse',
- 'pyptlib >= 0.0.5',
- 'pyyaml'
+ 'pyptlib >= 0.0.6',
+ 'pyyaml',
+ 'txsocksx'
],
)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/obfsproxy.git
More information about the Pkg-privacy-commits
mailing list