[Pkg-privacy-commits] [obfsproxy] 259/353: Incorporate feedback from hellais, and minor bug fixes
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 13:02:07 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 59c2ad0fd8fe20fb430352db6e98cf1feb90e74b
Author: Yawning Angel <yawning at schwanenlied.me>
Date: Sun Mar 9 23:31:07 2014 +0000
Incorporate feedback from hellais, and minor bug fixes
Changed based on feedback from hellias:
* handleCmdConnectFailure now traps errors
* sendReply no longer deals with parsing out the outgoing local address
* logging uses the obfsproxy logger again
* Fixed a bug where send_reply was used instead of sendReply
* The obfsproxy specific SOCKSv5 classes were renamed to OBFSSOCKSv5Outgoing
and OBFSSOCKSv5Protocol
Bugs I found:
* SOCKSv5Protocol.dataReceived() should actually work now (never called by
obfsproxy since it's overridden)
* _ByteBuffer.get_uint32() was always doing byte order conversion (method never
used)
---
obfsproxy/network/launch_transport.py | 2 +-
obfsproxy/network/socks.py | 26 ++++----
obfsproxy/network/socks5.py | 119 +++++++++++++++++-----------------
3 files changed, 74 insertions(+), 73 deletions(-)
diff --git a/obfsproxy/network/launch_transport.py b/obfsproxy/network/launch_transport.py
index b9d7e9b..9048dda 100644
--- a/obfsproxy/network/launch_transport.py
+++ b/obfsproxy/network/launch_transport.py
@@ -35,7 +35,7 @@ def launch_transport_listener(transport, bindaddr, role, remote_addrport, pt_con
listen_port = int(bindaddr[1]) if bindaddr else 0
if role == 'socks':
- factory = socks.SOCKSv5Factory(transport_class, pt_config)
+ factory = socks.OBFSSOCKSv5Factory(transport_class, pt_config)
elif role == 'ext_server':
assert(remote_addrport and ext_or_cookie_file)
factory = extended_orport.ExtORPortServerFactory(remote_addrport, ext_or_cookie_file, transport, transport_class, pt_config)
diff --git a/obfsproxy/network/socks.py b/obfsproxy/network/socks.py
index b55b7bc..528c724 100644
--- a/obfsproxy/network/socks.py
+++ b/obfsproxy/network/socks.py
@@ -20,7 +20,7 @@ def _split_socks_args(args_str):
return csv.reader([args_str], delimiter=';', escapechar='\\').next()
-class SOCKSv5Outgoing(socks5.SOCKSv5Outgoing, network.GenericProtocol):
+class OBFSSOCKSv5Outgoing(socks5.SOCKSv5Outgoing, network.GenericProtocol):
"""
Represents a downstream connection from the SOCKS server to the
destination.
@@ -48,14 +48,15 @@ class SOCKSv5Outgoing(socks5.SOCKSv5Outgoing, network.GenericProtocol):
self.socks = socksProtocol
network.GenericProtocol.__init__(self, socksProtocol.circuit)
- return super(SOCKSv5Outgoing, self).__init__(socksProtocol)
+ return super(OBFSSOCKSv5Outgoing, self).__init__(socksProtocol)
def connectionMade(self):
- self.socks.otherConn = self
- self.socks.set_up_circuit()
+ self.socks.set_up_circuit(self)
- # XXX: The transport should do this after handshaking
- self.socks.sendReply(socks5.SOCKSv5Reply.Succeeded)
+ # XXX: The transport should be doing this after handshaking since it
+ # calls, self.socks.sendReply(), when this changes to defer sending the
+ # reply back set self.socks.otherConn here.
+ super(OBFSSOCKSv5Outgoing, self).connectionMade()
def dataReceived(self, data):
log.debug("%s: Recived %d bytes." % (self.name, len(data)))
@@ -65,7 +66,7 @@ class SOCKSv5Outgoing(socks5.SOCKSv5Outgoing, network.GenericProtocol):
self.circuit.dataReceived(self.buffer, self)
-class SOCKSv5Protocol(socks5.SOCKSv5Protocol, network.GenericProtocol):
+class OBFSSOCKSv5Protocol(socks5.SOCKSv5Protocol, network.GenericProtocol):
"""
Represents an upstream connection from a SOCKS client to our SOCKS
server.
@@ -136,14 +137,13 @@ class SOCKSv5Protocol(socks5.SOCKSv5Protocol, network.GenericProtocol):
This is overriden so that our sub-classed SOCKSv5Outgoing gets created.
"""
- return protocol.ClientCreator(reactor, SOCKSv5Outgoing, self).connectTCP(addr, port)
+ return protocol.ClientCreator(reactor, OBFSSOCKSv5Outgoing, self).connectTCP(addr, port)
- def set_up_circuit(self):
- assert self.otherConn
- self.circuit.setDownstreamConnection(self.otherConn)
+ def set_up_circuit(self, otherConn):
+ self.circuit.setDownstreamConnection(otherConn)
self.circuit.setUpstreamConnection(self)
-class SOCKSv5Factory(protocol.Factory):
+class OBFSSOCKSv5Factory(protocol.Factory):
"""
A SOCKSv5 factory.
"""
@@ -163,4 +163,4 @@ class SOCKSv5Factory(protocol.Factory):
circuit = network.Circuit(self.transport_class())
- return SOCKSv5Protocol(circuit)
+ return OBFSSOCKSv5Protocol(circuit)
diff --git a/obfsproxy/network/socks5.py b/obfsproxy/network/socks5.py
index 0be77f4..ccadb48 100644
--- a/obfsproxy/network/socks5.py
+++ b/obfsproxy/network/socks5.py
@@ -1,9 +1,15 @@
from twisted.internet import reactor, protocol, error
-from twisted.python import log
+
+import obfsproxy.common.log as logging
+
import socket
import struct
+
+log = logging.get_obfslogger()
+
+
"""
SOCKS5 Server:
@@ -34,6 +40,7 @@ _SOCKS_RFC1929_VER = 0x01
_SOCKS_RFC1929_SUCCESS = 0x00
_SOCKS_RFC1929_FAIL = 0x01
+
class SOCKSv5Reply(object):
"""
SOCKSv5 reply codes
@@ -63,19 +70,34 @@ class SOCKSv5Outgoing(protocol.Protocol):
def connectionMade(self):
self.socks.otherConn = self
- self.socks.send_reply(SOCKSv5Reply.Succeeded)
+ try:
+ atype, addr, port = self.getRawBoundAddr()
+ self.socks.sendReply(SOCKSv5Reply.Succeeded, addr, port, atype)
+ except:
+ self.socks.sendReply(SOCKSv5Reply.GeneralFailure)
def connectionLost(self, reason):
self.socks.transport.loseConnection()
def dataReceived(self, data):
- self.socks.log(self, data)
- self.transport.write(data)
+ self.socks.write(data)
def write(self, data):
- self.socks.log(self, data)
self.transport.write(data)
+ def getRawBoundAddr(self):
+ host = self.transport.getHost()
+ port = host.port
+ af = socket.getaddrinfo(host.host, port, 0, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_NUMERICHOST | socket.AI_NUMERICSERV)[0][0]
+ raw_addr = socket.inet_pton(af, host.host)
+ if af == socket.AF_INET:
+ atype = _SOCKS_ATYP_IP_V4
+ elif af == socket.AF_INET6:
+ atype = _SOCKS_ATYP_IP_V6
+ else:
+ raise ValueError("Invalid Address Family")
+ return (atype, raw_addr, port)
+
class SOCKSv5Protocol(protocol.Protocol):
"""
@@ -114,8 +136,7 @@ class SOCKSv5Protocol(protocol.Protocol):
_SOCKS_CMD_UDP_ASSOCIATE
]
- def __init__(self, logging=None, reactor=reactor):
- self.logging = logging
+ def __init__(self, reactor=reactor):
self.reactor = reactor
self.state = self.ST_INIT
@@ -143,10 +164,10 @@ class SOCKSv5Protocol(protocol.Protocol):
self.processRequest()
elif self.state == self.ST_CONNECTING:
# This only happens when the client is busted
- log.msg("Client sent data before receiving response")
+ log.error("Client sent data before receiving response")
self.transport.loseConnection()
else:
- log.msg("Invalid state in SOCKS5 Server: '%d'" % self.state)
+ log.error("Invalid state in SOCKS5 Server: '%d'" % self.state)
self.transport.loseConnection()
def processEstablishedData(self, data):
@@ -165,11 +186,11 @@ class SOCKSv5Protocol(protocol.Protocol):
ver = msg.get_uint8()
nmethods = msg.get_uint8()
if ver != _SOCKS_VERSION:
- log.msg("Invalid SOCKS version: '%d'" % ver)
+ log.error("Invalid SOCKS version: '%d'" % ver)
self.transport.loseConnection()
return
if nmethods == 0:
- log.msg("No Authentication method(s) present")
+ log.error("No Authentication method(s) present")
self.transport.loseConnection()
return
if len(msg) < nmethods:
@@ -182,12 +203,12 @@ class SOCKSv5Protocol(protocol.Protocol):
self.authMethod = method
break
if self.authMethod == _SOCKS_AUTH_NO_ACCEPTABLE_METHODS:
- log.msg("No Acceptable Authentication Methods")
+ log.error("No Acceptable Authentication Methods")
self.authMethod = _SOCKS_AUTH_NO_ACCEPTABLE_METHODS
# Ensure there is no trailing garbage
if len(msg) > 0:
- log.msg("Peer sent trailing garbage after method select")
+ log.error("Peer sent trailing garbage after method select")
self.transport.loseConnection()
return
self.buf.clear()
@@ -213,7 +234,7 @@ class SOCKSv5Protocol(protocol.Protocol):
self.AUTH_METHOD_VTABLE[self.authMethod](self)
else:
# Should *NEVER* happen
- log.msg("Peer sent data when we failed to negotiate auth")
+ log.error("Peer sent data when we failed to negotiate auth")
self.buf.clear()
self.transport.loseConnection()
@@ -230,11 +251,11 @@ class SOCKSv5Protocol(protocol.Protocol):
ver = msg.get_uint8()
ulen = msg.get_uint8()
if ver != _SOCKS_RFC1929_VER:
- log.msg("Invalid RFC1929 version: '%d'" % ver)
+ log.error("Invalid RFC1929 version: '%d'" % ver)
self.sendRfc1929Reply(False)
return
if ulen == 0:
- log.msg("Username length is 0")
+ log.error("Username length is 0")
self.sendRfc1929Reply(False)
return
@@ -250,14 +271,14 @@ class SOCKSv5Protocol(protocol.Protocol):
if len(msg) < plen:
return
if plen == 0:
- log.msg("Password length is 0")
+ log.error("Password length is 0")
self.sendRfc1929Reply(False)
return
passwd = msg.get(plen)
# Ensure there is no trailing garbage
if len(msg) > 0:
- log.msg("Peer sent trailing garbage after RFC1929 auth")
+ log.error("Peer sent trailing garbage after RFC1929 auth")
self.transport.loseConnection()
return
self.buf.clear()
@@ -313,15 +334,15 @@ class SOCKSv5Protocol(protocol.Protocol):
rsv = msg.get_uint8()
atyp = msg.get_uint8()
if ver != _SOCKS_VERSION:
- log.msg("Invalid SOCKS version: '%d'" % ver)
+ log.error("Invalid SOCKS version: '%d'" % ver)
self.sendReply(SOCKSv5Reply.GeneralFailure)
return
if cmd not in self.ACCEPTABLE_CMDS:
- log.msg("Invalid SOCKS command: '%d'" % cmd)
+ log.error("Invalid SOCKS command: '%d'" % cmd)
self.sendReply(SOCKSv5Reply.CommandNotSupported)
return
if rsv != _SOCKS_RSV:
- log.msg("Invalid SOCKS RSV: '%d'" % rsv)
+ log.error("Invalid SOCKS RSV: '%d'" % rsv)
self.sendReply(SOCKSv5Reply.GeneralFailure)
return
@@ -337,7 +358,7 @@ class SOCKSv5Protocol(protocol.Protocol):
try:
addr = socket.inet_ntop(socket.AF_INET6, str(msg.get(16)))
except:
- log.msg("Failed to parse IPv6 address")
+ log.error("Failed to parse IPv6 address")
self.sendReply(SOCKSv5Reply.AddressTypeNotSupported)
return
elif atyp == _SOCKS_ATYP_DOMAINNAME:
@@ -345,14 +366,14 @@ class SOCKSv5Protocol(protocol.Protocol):
return
alen = msg.get_uint8()
if alen == 0:
- log.msg("Domain name length is 0")
+ log.error("Domain name length is 0")
self.sendReply(SOCKSv5Reply.GeneralFailure)
return
if len(msg) < alen:
return
addr = str(msg.get(alen))
else:
- log.msg("Invalid SOCKS address type: '%d'" % atyp)
+ log.error("Invalid SOCKS address type: '%d'" % atyp)
self.sendReply(SOCKSv5Reply.AddressTypeNotSupported)
return
@@ -363,7 +384,7 @@ class SOCKSv5Protocol(protocol.Protocol):
# Ensure there is no trailing garbage
if len(msg) > 0:
- log.msg("Peer sent trailing garbage after request")
+ log.error("Peer sent trailing garbage after request")
self.transport.loseConnection()
return
self.buf.clear()
@@ -376,7 +397,7 @@ class SOCKSv5Protocol(protocol.Protocol):
self.processCmdUdpAssociate(addr, port)
else:
# Should *NEVER* happen
- log.msg("Unimplemented command received")
+ log.error("Unimplemented command received")
self.transport.loseConnection()
def processCmdConnect(self, addr, port):
@@ -389,10 +410,13 @@ class SOCKSv5Protocol(protocol.Protocol):
self.state = self.ST_CONNECTING
def connectClass(self, addr, port, klass, *args):
- return protocol.ClientCreator(reactor, klass, *args).connectTCP(addr, port)
+ return protocol.ClientCreator(self.reactor, klass, *args).connectTCP(addr, port)
def handleCmdConnectFailure(self, failure):
- log.err(failure, "Failed to connect to peer")
+ log.error("CMD CONNECT: %s" % failure.getErrorMessage())
+ failure.trap(error.NoRouteError, error.ConnectionRefusedError,
+ error.TCPTimedOutError, error.TimeoutError,
+ error.UnsupportedAddressFamily)
# Map common twisted errors to SOCKS error codes
if failure.type == error.NoRouteError:
@@ -412,7 +436,7 @@ class SOCKSv5Protocol(protocol.Protocol):
def processCmdUdpAssociate(self, addr, port):
self.sendReply(SOCKSv5Reply.CommandNotSupported)
- def sendReply(self, reply):
+ def sendReply(self, reply, addr=struct.pack("!I", 0), port=0, atype=_SOCKS_ATYP_IP_V4):
"""
Send a reply to the request, and complete circuit setup
"""
@@ -421,47 +445,24 @@ class SOCKSv5Protocol(protocol.Protocol):
msg.add_uint8(_SOCKS_VERSION)
msg.add_uint8(reply)
msg.add_uint8(_SOCKS_RSV)
- if reply == SOCKSv5Reply.Succeeded:
- host = self.transport.getHost()
- port = host.port
- try:
- raw_addr = socket.inet_aton(host.host)
- msg.add_uint8(_SOCKS_ATYP_IP_V4)
- msg.add(raw_addr)
- except socket.error:
- try:
- raw_addr = socket.inet_pton(socket.AF_INET6, host.host)
- msg.add_uint8(_SOCKS_ATYP_IP_V6)
- msg.add(raw_addr)
- except:
- log.msg("Failed to parse bound address")
- self.sendReply(SOCKSv5Reply.GeneralFailure)
- return
- msg.add_uint16(port, True)
- self.transport.write(str(msg))
+ msg.add_uint8(atype)
+ msg.add(addr)
+ msg.add_uint16(port, True)
+ self.transport.write(str(msg))
+ if reply == SOCKSv5Reply.Succeeded:
self.state = self.ST_ESTABLISHED
else:
- msg.add_uint8(_SOCKS_ATYP_IP_V4)
- msg.add_uint32(0, True)
- msg.add_uint16(0, True)
- self.transport.write(str(msg))
self.transport.loseConnection()
- def log(self, proto, data):
- pass
-
class SOCKSv5Factory(protocol.Factory):
"""
A SOCKSv5 Factory.
"""
- def __init__(self, log):
- self.logging = log
-
def buildProtocol(self, addr):
- return SOCKSv5Protocol(self.logging, reactor)
+ return SOCKSv5Protocol(reactor)
class _ByteBuffer(bytearray):
@@ -538,7 +539,7 @@ class _ByteBuffer(bytearray):
if ntohl:
ret = struct.unpack("!I", self[0:4])[0]
else:
- ret = struct.unpack("!I", self[0:4])[0]
+ ret = struct.unpack("I", self[0:4])[0]
del self[0:2]
return ret
--
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