[Pkg-privacy-commits] [Git][pkg-privacy-team/txtorcon][master] 4 commits: New upstream version 19.0.0

Iain Learmonth irl at debian.org
Thu Jun 13 22:24:32 BST 2019



Iain Learmonth pushed to branch master at Privacy Maintainers / txtorcon


Commits:
d1e66fa1 by Iain R. Learmonth at 2019-06-13T21:09:26Z
New upstream version 19.0.0
- - - - -
3a0738d5 by Iain R. Learmonth at 2019-06-13T21:09:28Z
Update upstream source from tag 'upstream/19.0.0'

Update to upstream version '19.0.0'
with Debian dir c11dd5e7c616f9d90d708ad1a357e32ddb2a8a68
- - - - -
dbc01730 by Iain R. Learmonth at 2019-06-13T21:14:16Z
d/patches: Refreshed remove-privacy-infringing-buttons

- - - - -
5a2684be by Iain R. Learmonth at 2019-06-13T21:23:59Z
d/changelog: Update for release

- - - - -


18 changed files:

- Makefile
- PKG-INFO
- README.rst
- debian/changelog
- debian/patches/remove-privacy-infringing-buttons.patch
- docs/release-checklist.rst
- docs/releases.rst
- examples/connect.py
- test/test_controller.py
- test/test_torcontrolprotocol.py
- test/test_torstate.py
- txtorcon.egg-info/PKG-INFO
- txtorcon/_metadata.py
- txtorcon/controller.py
- txtorcon/onion.py
- txtorcon/torconfig.py
- txtorcon/torcontrolprotocol.py
- txtorcon/torstate.py


Changes:

=====================================
Makefile
=====================================
@@ -1,6 +1,6 @@
 .PHONY: test html counts coverage sdist clean install doc integration diagrams
 default: test
-VERSION = 18.3.0
+VERSION = 19.0.0
 
 test:
 	PYTHONPATH=. trial --reporter=text test


=====================================
PKG-INFO
=====================================
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: txtorcon
-Version: 18.3.0
+Version: 19.0.0
 Summary: 
     Twisted-based Tor controller client, with state-tracking and
     configuration abstractions.
@@ -44,10 +44,6 @@ Description:
             :target: https://txtorcon.readthedocs.io/en/latest
             :alt: ReadTheDocs
         
-        .. image:: http://api.flattr.com/button/flattr-badge-large.png
-            :target: http://flattr.com/thing/1689502/meejahtxtorcon-on-GitHub
-            :alt: flattr
-        
         .. image:: https://landscape.io/github/meejah/txtorcon/master/landscape.svg?style=flat
             :target: https://landscape.io/github/meejah/txtorcon/master
             :alt: Code Health


=====================================
README.rst
=====================================
@@ -31,10 +31,6 @@
     :target: https://txtorcon.readthedocs.io/en/latest
     :alt: ReadTheDocs
 
-.. image:: http://api.flattr.com/button/flattr-badge-large.png
-    :target: http://flattr.com/thing/1689502/meejahtxtorcon-on-GitHub
-    :alt: flattr
-
 .. image:: https://landscape.io/github/meejah/txtorcon/master/landscape.svg?style=flat
     :target: https://landscape.io/github/meejah/txtorcon/master
     :alt: Code Health


=====================================
debian/changelog
=====================================
@@ -1,3 +1,11 @@
+txtorcon (19.0.0-1) experimental; urgency=medium
+
+  * New upstream version 19.0.0
+  * d/patches:
+    - Refreshed remove-privacy-infringing-buttons.patch
+
+ -- Iain R. Learmonth <irl at debian.org>  Thu, 13 Jun 2019 22:23:49 +0100
+
 txtorcon (18.3.0-1) unstable; urgency=medium
 
   * New upstream version 18.3.0


=====================================
debian/patches/remove-privacy-infringing-buttons.patch
=====================================
@@ -11,7 +11,7 @@ consults local documentation, which shouldn't happen.
 
 --- a/README.rst
 +++ b/README.rst
-@@ -11,35 +11,6 @@
+@@ -11,31 +11,6 @@
  
  
  
@@ -35,10 +35,6 @@ consults local documentation, which shouldn't happen.
 -    :target: https://txtorcon.readthedocs.io/en/latest
 -    :alt: ReadTheDocs
 -
--.. image:: http://api.flattr.com/button/flattr-badge-large.png
--    :target: http://flattr.com/thing/1689502/meejahtxtorcon-on-GitHub
--    :alt: flattr
--
 -.. image:: https://landscape.io/github/meejah/txtorcon/master/landscape.svg?style=flat
 -    :target: https://landscape.io/github/meejah/txtorcon/master
 -    :alt: Code Health


=====================================
docs/release-checklist.rst
=====================================
@@ -23,7 +23,7 @@ Release Checklist
    * update heading, date
 
 * on both signing-machine and build-machine shells:
-   * export VERSION=18.0.0
+   * export VERSION=19.0.0
 
 * (if on signing machine) "make dist" and "make dist-sigs"
    * creates:


=====================================
docs/releases.rst
=====================================
@@ -15,11 +15,22 @@ that will be "19.2.1".
 
 See also :ref:`api_stability`.
 
-
 unreleased
 ----------
 
-`git master <https://github.com/meejah/txtorcon>`_ *will likely become v19.0.0*
+`git master <https://github.com/meejah/txtorcon>`_ *will likely become v19.1.0*
+
+
+v19.0.0
+-------
+
+January 15, 2019
+
+ * `txtorcon-19.0.0.tar.gz <http://timaq4ygg2iegci7.onion/txtorcon-19.0.0.tar.gz>`_ (`PyPI <https://pypi.python.org/pypi/txtorcon/19.0.0>`_ (:download:`local-sig </../signatues/txtorcon-19.0.0.tar.gz.asc>` or `github-sig <https://github.com/meejah/txtorcon/blob/master/signatues/txtorcon-19.0.0.tar.gz.asc?raw=true>`_) (`source <https://github.com/meejah/txtorcon/archive/v19.0.0.tar.gz>`_)
+ * add :func:`TorControlProtocol.when_disconnected` (will replace `.on_disconnect`)
+ * add `detach=` kwarg to :func:`Tor.create_onion_service`
+ * add `purpose=` kwarg to :func:`TorState.build_circuit`
+
 
 v18.3.0
 -------


=====================================
examples/connect.py
=====================================
@@ -16,9 +16,11 @@ def main(reactor):
     tor = yield txtorcon.connect(reactor, ep)
     print("Connected to Tor {version}".format(version=tor.protocol.version))
 
-    state = yield tor.create_state()
-    # or:
-    # state = yield txtorcon.TorState.from_protocol(tor.protocol)
-    print("Tor state created. Circuits:")
-    for circuit in state.circuits.values():
-        print("  {circuit.id}: {circuit.path}".format(circuit=circuit))
+    d = tor.protocol.when_disconnected()
+
+    def its_gone(value):
+        print("Connection gone")
+    d.addCallback(its_gone)
+
+    tor.protocol.transport.loseConnection()
+    yield d


=====================================
test/test_controller.py
=====================================
@@ -3,7 +3,7 @@ import six
 import functools
 from os.path import join
 from mock import Mock, patch
-from six.moves import StringIO
+from io import BytesIO
 
 from twisted.internet.interfaces import IReactorCore
 from twisted.internet.interfaces import IListeningPort
@@ -51,7 +51,7 @@ class FakeProcessTransport(proto_helpers.StringTransportWithDisconnection):
         )
 
     def closeStdin(self):
-        self.process_protocol.outReceived(b"Bootstrap")
+        self.process_protocol.outReceived(b"Opening Control listener")
         return
 
 
@@ -570,12 +570,12 @@ class LaunchTorTests(unittest.TestCase):
             return proto.post_bootstrap
 
         def on_protocol(proto):
-            proto.errReceived('Something went horribly wrong!\n')
+            proto.errReceived(b'Something went horribly wrong!\n')
 
         trans = FakeProcessTransport()
         trans.protocol = Mock()
-        fakeout = StringIO()
-        fakeerr = StringIO()
+        fakeout = BytesIO()
+        fakeerr = BytesIO()
         creator = functools.partial(connector, Mock(), Mock())
         try:
             yield launch(
@@ -587,8 +587,8 @@ class LaunchTorTests(unittest.TestCase):
             )
             self.fail()  # should't get callback
         except RuntimeError as e:
-            self.assertEqual('', fakeout.getvalue())
-            self.assertEqual('Something went horribly wrong!\n', fakeerr.getvalue())
+            self.assertEqual(b'', fakeout.getvalue())
+            self.assertEqual(b'Something went horribly wrong!\n', fakeerr.getvalue())
             self.assertTrue(
                 'Something went horribly wrong!' in str(e)
             )
@@ -599,7 +599,7 @@ class LaunchTorTests(unittest.TestCase):
         trans = FakeProcessTransport()
 
         def on_protocol(proto):
-            proto.outReceived(b'Bootstrapped 100%\n')
+            proto.outReceived(b'Opening Control listener\n')
         reactor = FakeReactor(self, trans, on_protocol, [1, 2, 3])
 
         fails = ['one']


=====================================
test/test_torcontrolprotocol.py
=====================================
@@ -215,6 +215,38 @@ class DisconnectionTests(unittest.TestCase):
         self.protocol.connectionLost(f)
         self.assertTrue(it_was_called.yes)
 
+    def test_when_disconnect(self):
+        """
+        see that we get our callback for when_disconnected if the
+        transport goes away
+        """
+        def it_was_called(arg):
+            it_was_called.yes = True
+            return None
+        it_was_called.yes = False
+
+        d = self.protocol.when_disconnected()
+        d.addCallback(it_was_called)
+        f = failure.Failure(error.ConnectionDone("It's all over"))
+        self.protocol.connectionLost(f)
+        self.assertTrue(it_was_called.yes)
+
+    def test_when_disconnect_error(self):
+        """
+        see that we get our errback for when_disconnected if the
+        transport goes away
+        """
+        def it_was_called(arg):
+            it_was_called.yes = True
+            return None
+        it_was_called.yes = False
+
+        d = self.protocol.when_disconnected()
+        d.addErrback(it_was_called)
+        f = failure.Failure(RuntimeError("sadness"))
+        self.protocol.connectionLost(f)
+        self.assertTrue(it_was_called.yes)
+
     def test_disconnect_errback(self):
         """
         see that we get our callback on_disconnect if the transport


=====================================
test/test_torstate.py
=====================================
@@ -1399,7 +1399,6 @@ s Fast Guard Running Stable Valid
         circ = FakeCircuit()
 
         def _build(*args, **kw):
-            print("DING {} {}".format(args, kw))
             return defer.succeed(circ)
         self.state.build_circuit = _build
 
@@ -1411,7 +1410,6 @@ s Fast Guard Running Stable Valid
         # be closed
         d = build_timeout_circuit(self.state, clock, path, timeout, using_guards=False)
         clock.advance(1)
-        print("DING {}".format(self.state))
         d.cancel()
 
         with self.assertRaises(CircuitBuildTimedOutError):
@@ -1509,3 +1507,30 @@ s Fast Guard Running Stable Valid
         d.addErrback(check_reason)
 
         return d
+
+    def test_build_circuit_with_purpose(self):
+        class FakeRouter:
+            def __init__(self, i):
+                self.id_hex = i
+                self.flags = []
+
+        path = []
+        for x in range(3):
+            path.append(FakeRouter("$%040d" % x))
+        path[0].flags = ['guard']
+
+        d = self.state.build_circuit(path, using_guards=True, purpose="general")
+        d.addCallback(self.circuit_callback)
+
+        self.assertEqual(self.transport.value(), b'EXTENDCIRCUIT 0 0000000000000000000000000000000000000000,0000000000000000000000000000000000000001,0000000000000000000000000000000000000002 purpose=general\r\n')
+        self.send(b"250 EXTENDED 1234")
+        # we can't just .send(b'650 CIRC 1234 BUILT') this because we
+        # didn't fully hook up the protocol to the state, e.g. via
+        # post_bootstrap etc.
+        self.state.circuits[1234].update(['1234', 'FAILED', 'REASON=TIMEOUT'])
+
+        def check_reason(fail):
+            self.assertEqual(fail.value.reason, 'TIMEOUT')
+        d.addErrback(check_reason)
+
+        return d


=====================================
txtorcon.egg-info/PKG-INFO
=====================================
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: txtorcon
-Version: 18.3.0
+Version: 19.0.0
 Summary: 
     Twisted-based Tor controller client, with state-tracking and
     configuration abstractions.
@@ -44,10 +44,6 @@ Description:
             :target: https://txtorcon.readthedocs.io/en/latest
             :alt: ReadTheDocs
         
-        .. image:: http://api.flattr.com/button/flattr-badge-large.png
-            :target: http://flattr.com/thing/1689502/meejahtxtorcon-on-GitHub
-            :alt: flattr
-        
         .. image:: https://landscape.io/github/meejah/txtorcon/master/landscape.svg?style=flat
             :target: https://landscape.io/github/meejah/txtorcon/master
             :alt: Code Health


=====================================
txtorcon/_metadata.py
=====================================
@@ -1,6 +1,6 @@
-__version__ = '18.3.0'
+__version__ = '19.0.0'
 __author__ = 'meejah'
 __contact__ = 'meejah at meejah.ca'
 __url__ = 'https://github.com/meejah/txtorcon'
 __license__ = 'MIT'
-__copyright__ = 'Copyright 2012-2018'
+__copyright__ = 'Copyright 2012-2019'


=====================================
txtorcon/controller.py
=====================================
@@ -945,7 +945,9 @@ class Tor(object):
     # method names are kind of long (not-ideal)
 
     @inlineCallbacks
-    def create_onion_service(self, ports, private_key=None, version=3, progress=None, await_all_uploads=False, single_hop=None):
+    def create_onion_service(self, ports, private_key=None, version=3,
+                             progress=None, await_all_uploads=False,
+                             single_hop=None, detach=None):
         """
         Create a new Onion service
 
@@ -986,6 +988,12 @@ class Tor(object):
             that Tor options `HiddenServiceSingleHopMode`,
             `HiddenServiceNonAnonymousMode` must be set to `1` and there
             must be no `SOCKSPort` configured for this to actually work.
+
+        :param detach: if True, the created service won't be tied to
+            this control connection and will still be active when this
+            control-connection goes away (this means the service will
+            appear in `GETINFO onions/detached` to all other
+            controllers)
         """
         if version not in (2, 3):
             raise ValueError(
@@ -1005,6 +1013,7 @@ class Tor(object):
             progress=progress,
             await_all_uploads=await_all_uploads,
             single_hop=single_hop,
+            detach=detach,
         )
         returnValue(service)
 
@@ -1234,7 +1243,7 @@ class TorProcessProtocol(protocol.ProcessProtocol):
         # tor_connection_failed)
         txtorlog.msg(data)
         if not self.attempted_connect and self.connection_creator \
-                and b'Bootstrap' in data:
+                and b'Opening Control listener' in data:
             self.attempted_connect = True
             # hmmm, we don't "do" anything with this Deferred?
             # (should it be connected to the when_connected
@@ -1273,7 +1282,8 @@ class TorProcessProtocol(protocol.ProcessProtocol):
         if self.kill_on_stderr:
             self.transport.loseConnection()
             raise RuntimeError(
-                "Received stderr output from slave Tor process: " + data)
+                "Received stderr output from slave Tor process: " + data.decode('utf8')
+            )
 
     def cleanup(self):
         """


=====================================
txtorcon/onion.py
=====================================
@@ -1118,7 +1118,6 @@ class FilesystemAuthenticatedOnionService(object):
         config.HiddenServices.append(fhs)
 
         def translate_progress(pct, tag, description):
-            print("OHAI {} {}".format(pct, tag))
             # XXX fixme actually translate..
             if progress:
                 progress(pct, tag, description)


=====================================
txtorcon/torconfig.py
=====================================
@@ -1104,7 +1104,7 @@ class TorConfig(object):
         # then...?)
         try:
             ephemeral = yield self.protocol.get_info('onions/current')
-        except Exception as e:
+        except Exception:
             self.config['EphemeralOnionServices'] = []
         else:
             onions = []


=====================================
txtorcon/torcontrolprotocol.py
=====================================
@@ -23,7 +23,7 @@ from txtorcon.log import txtorlog
 
 from txtorcon.interface import ITorControlProtocol
 from .spaghetti import FSM, State, Transition
-from .util import maybe_coroutine
+from .util import maybe_coroutine, SingleObserver
 
 
 DEFAULT_VALUE = 'DEFAULT'
@@ -271,6 +271,11 @@ class TorControlProtocol(LineOnlyReceiver):
         there was an error, the errback is called instead.
         """
 
+        self._when_disconnected = SingleObserver()
+        """
+        Private. See :func:`.when_disconnected`
+        """
+
         self.post_bootstrap = defer.Deferred()
         """
         This Deferred is triggered when we're done setting up
@@ -648,6 +653,13 @@ class TorControlProtocol(LineOnlyReceiver):
         self._maybe_issue_command()
         return d
 
+    def when_disconnected(self):
+        """
+        :returns: a Deferred that fires when (if) we disconnect from our
+            Tor process.
+        """
+        return self._when_disconnected.when_fired()
+
     # the remaining methods are internal API implementations,
     # callbacks and state-tracking methods -- you shouldn't have any
     # need to call them.
@@ -672,11 +684,17 @@ class TorControlProtocol(LineOnlyReceiver):
     def connectionLost(self, reason):
         "Protocol API"
         txtorlog.msg('connection terminated: ' + str(reason))
+        if reason.check(ConnectionDone):
+            self._when_disconnected.fire(self)
+        else:
+            self._when_disconnected.fire(reason)
+
         # ...and this is why we don't do on_disconnect = Deferred() :(
         # and instead should have had on_disconnect() method that
         # returned a new Deferred to each caller..(we're checking if
         # this Deferred has any callbacks because if it doesn't we'll
         # generate an "Unhandled error in Deferred")
+        # XXX (deprecate this)
         if not self.on_disconnect.called and self.on_disconnect.callbacks:
             if reason.check(ConnectionDone):
                 self.on_disconnect.callback(self)


=====================================
txtorcon/torstate.py
=====================================
@@ -545,7 +545,7 @@ class TorState(object):
         circ.update([str(circ_id), 'EXTENDED'])
         return circ
 
-    def build_circuit(self, routers=None, using_guards=True):
+    def build_circuit(self, routers=None, using_guards=True, purpose=None):
         """
         Builds a circuit consisting of exactly the routers specified,
         in order.  This issues an EXTENDCIRCUIT call to Tor with all
@@ -586,6 +586,9 @@ class TorState(object):
                     cmd += router.decode('utf8')
                 else:
                     cmd += router.id_hex[1:]
+
+            if purpose is not None:
+                cmd += " purpose={}".format(purpose)
         d = self.protocol.queue_command(cmd)
         d.addCallback(self._find_circuit_after_extend)
         return d



View it on GitLab: https://salsa.debian.org/pkg-privacy-team/txtorcon/compare/884e91c1ede5e5ccb14b95d824baebdefe8a1158...5a2684be38c0547fbd545a34769850b45d927410

-- 
View it on GitLab: https://salsa.debian.org/pkg-privacy-team/txtorcon/compare/884e91c1ede5e5ccb14b95d824baebdefe8a1158...5a2684be38c0547fbd545a34769850b45d927410
You're receiving this email because of your account on salsa.debian.org.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-privacy-commits/attachments/20190613/e9d116c2/attachment-0001.html>


More information about the Pkg-privacy-commits mailing list