[Pkg-privacy-commits] [obfsproxy] 77/353: Revive the b64 transport.
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 13:01:42 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 ec51fbc409a661f004e920982197b94d49d551a9
Author: George Kadianakis <desnacked at riseup.net>
Date: Sun Oct 28 20:18:02 2012 +0200
Revive the b64 transport.
---
obfsproxy/network/network.py | 7 +---
obfsproxy/test/tester.py | 10 +++++
obfsproxy/test/transports/b64_test.py | 62 +++++++++++++++++++++++++++
obfsproxy/transports/b64.py | 79 +++++++++++++++++++++++------------
4 files changed, 127 insertions(+), 31 deletions(-)
diff --git a/obfsproxy/network/network.py b/obfsproxy/network/network.py
index 1e41bca..819518f 100644
--- a/obfsproxy/network/network.py
+++ b/obfsproxy/network/network.py
@@ -140,15 +140,15 @@ class Circuit(Protocol):
Requires both downstream and upstream connections to be set.
"""
- log.debug("%s: Received %d bytes." % (self.name, len(data)))
-
assert(self.downstream and self.upstream)
assert((conn is self.downstream) or (conn is self.upstream))
try:
if conn is self.downstream:
+ log.debug("%s: downstream: Received %d bytes." % (self.name, len(data)))
self.transport.receivedDownstream(data, self)
else:
+ log.debug("%s: upstream: Received %d bytes." % (self.name, len(data)))
self.transport.receivedUpstream(data, self)
except base.PluggableTransportError, err: # Our transport didn't like that data.
log.info("%s: %s: Closing circuit." % (self.name, str(err)))
@@ -246,9 +246,6 @@ class StaticDestinationProtocol(Protocol):
log.debug("%s: dataReceived called without a reason.", self.name)
return
- log.debug("%s: Received %d bytes (and %d cached):\n%s" \
- % (self.name, len(data), len(self.buffer), repr(data)))
-
# Add the received data to the buffer.
self.buffer.write(data)
diff --git a/obfsproxy/test/tester.py b/obfsproxy/test/tester.py
index b2d9ea5..8b67b9c 100644
--- a/obfsproxy/test/tester.py
+++ b/obfsproxy/test/tester.py
@@ -185,6 +185,7 @@ class DirectTest(object):
def setUp(self):
self.output_reader = ReadWorker(("127.0.0.1", EXIT_PORT))
self.obfs_server = Obfsproxy(self.server_args)
+ time.sleep(0.1)
self.obfs_client = Obfsproxy(self.client_args)
self.input_chan = connect_with_retry(("127.0.0.1", ENTRY_PORT))
self.input_chan.settimeout(SOCKET_TIMEOUT)
@@ -237,6 +238,15 @@ class DirectObfs2(DirectTest, unittest.TestCase):
"127.0.0.1:%d" % ENTRY_PORT,
"--dest=127.0.0.1:%d" % SERVER_PORT)
+class DirectB64(DirectTest, unittest.TestCase):
+ transport = "b64"
+ server_args = ("b64", "server",
+ "127.0.0.1:%d" % SERVER_PORT,
+ "--dest=127.0.0.1:%d" % EXIT_PORT)
+ client_args = ("b64", "client",
+ "127.0.0.1:%d" % ENTRY_PORT,
+ "--dest=127.0.0.1:%d" % SERVER_PORT)
+
TEST_FILE = """\
THIS IS A TEST FILE. IT'S USED BY THE INTEGRATION TESTS.
diff --git a/obfsproxy/test/transports/b64_test.py b/obfsproxy/test/transports/b64_test.py
new file mode 100644
index 0000000..cb85e69
--- /dev/null
+++ b/obfsproxy/test/transports/b64_test.py
@@ -0,0 +1,62 @@
+import unittest
+
+import obfsproxy.transports.b64 as b64
+
+class test_b64_splitting(unittest.TestCase):
+ def _helper_splitter(self, string, expected_chunks):
+ chunks = b64._get_b64_chunks_from_str(string)
+ self.assertEqual(chunks, expected_chunks)
+
+ def test_1(self):
+ string = "on==the==left==hand==side=="
+ expected = ["on==", "the==", "left==", "hand==", "side=="]
+ self._helper_splitter(string, expected)
+
+ def test_2(self):
+ string = "on=the=left=hand=side="
+ expected = ["on=", "the=", "left=", "hand=", "side="]
+ self._helper_splitter(string, expected)
+
+ def test_3(self):
+ string = "on==the=left==hand=side=="
+ expected = ["on==", "the=", "left==", "hand=", "side=="]
+ self._helper_splitter(string, expected)
+
+ def test_4(self):
+ string = "on==the==left=hand=side"
+ expected = ["on==", "the==", "left=", "hand=", "side"]
+ self._helper_splitter(string, expected)
+
+ def test_5(self):
+ string = "onthelefthandside=="
+ expected = ["onthelefthandside=="]
+ self._helper_splitter(string, expected)
+
+ def test_6(self):
+ string = "onthelefthandside"
+ expected = ["onthelefthandside"]
+ self._helper_splitter(string, expected)
+
+ def test_7(self):
+ string = "onthelefthandside="
+ expected = ["onthelefthandside="]
+ self._helper_splitter(string, expected)
+
+ def test_8(self):
+ string = "side=="
+ expected = ["side=="]
+ self._helper_splitter(string, expected)
+
+ def test_9(self):
+ string = "side="
+ expected = ["side="]
+ self._helper_splitter(string, expected)
+
+ def test_10(self):
+ string = "side"
+ expected = ["side"]
+ self._helper_splitter(string, expected)
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/obfsproxy/transports/b64.py b/obfsproxy/transports/b64.py
index bd7c5d4..9a83b73 100644
--- a/obfsproxy/transports/b64.py
+++ b/obfsproxy/transports/b64.py
@@ -9,51 +9,78 @@ import base64
import obfsproxy.common.log as log
-class B64Daemon(BaseDaemon):
+def _get_b64_chunks_from_str(string):
+ """
+ Given a 'string' of concatenated base64 objects, return a list
+ with the objects.
+ Assumes that the objects are well-formed base64 strings. Also
+ assumes that the padding character of base64 is '='.
"""
- B64Daemon is the base class for B64Client and B64Server.
- Since the protocol is so simple, B64Daemon provides all of the functionality for the b64 protocol implementation.
+ chunks = []
+
+ while True:
+ pad_loc = string.find('=')
+ if pad_loc < 0 or pad_loc == len(string)-1 or pad_loc == len(string)-2:
+ # If there is no padding, or it's the last chunk: append
+ # it to chunks and return.
+ chunks.append(string)
+ return chunks
+
+ if pad_loc != len(string)-1 and string[pad_loc+1] == '=': # double padding
+ pad_loc += 1
+
+ # Append the object to the chunks, and prepare the string for
+ # the next iteration.
+ chunks.append(string[:pad_loc+1])
+ string = string[pad_loc+1:]
+
+ return chunks
+
+class B64Daemon(BaseDaemon):
+ """
+ Implements the b64 protocol. A protocol that encodes data with
+ base64 before pushing them to the network.
"""
def receivedDownstream(self, data, circuit):
- """ XXX DOCDOC
- receivedDownstream is the event which is called when bytes are received from the downstream socket.
- The b64 protocol encodes them with the b64 function and then writes the result to the upstream socket.
"""
+ Got data from downstream; relay them upstream.
+ """
+
+ decoded_data = ''
- log.warning("downstream: Received '''%s'''" % (str(data)))
- circuit.upstream.write(base64.b64decode(data))
- return ''
+ # TCP is a stream protocol: the data we received might contain
+ # more than one b64 chunk. We should inspect the data and
+ # split it into multiple chunks.
+ b64_chunks = _get_b64_chunks_from_str(data.peek())
+
+ # Now b64 decode each chunk and append it to the our decoded
+ # data.
+ for chunk in b64_chunks:
+ try:
+ decoded_data += base64.b64decode(chunk)
+ except TypeError:
+ log.info("We got corrupted b64 ('%s')." % chunk)
+ return
+
+ data.drain()
+ circuit.upstream.write(decoded_data)
def receivedUpstream(self, data, circuit):
"""
- receivedUpstream is the event which is called when bytes are received from the upstream socket.
- The b64 protocol encodes them with the b64 function and then writes the result to the downstream socket.
+ Got data from upstream; relay them downstream.
"""
- log.warning("upstream: Received '''%s'''" % (str(data)))
- circuit.downstream.write(base64.b64encode(data))
- return ''
+ circuit.downstream.write(base64.b64encode(data.read()))
+ return
class B64Client(B64Daemon):
-
- """
- B64Client is a client for the 'b64' protocol.
- Since this protocol is so simple, the client and the server are identical and both just trivially subclass B64Daemon.
- """
-
pass
class B64Server(B64Daemon):
-
- """
- B64Server is a server for the 'b64' protocol.
- Since this protocol is so simple, the client and the server are identical and both just trivially subclass B64Daemon.
- """
-
pass
--
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