From ddc3f72afbae8396a9bb6fdded11d469fba9d1e5 Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Fri, 17 Feb 2017 01:17:51 +0000
Subject: [PATCH 01/10] Make TorManager accept plugins

---
 src/Tor/TorManager.py | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/Tor/TorManager.py b/src/Tor/TorManager.py
index b91cd937..c998570a 100644
--- a/src/Tor/TorManager.py
+++ b/src/Tor/TorManager.py
@@ -20,9 +20,11 @@ except:
     from gevent.lock import RLock
 from util import helper
 from Debug import Debug
+from Plugin import PluginManager
 
 
-class TorManager:
+@PluginManager.acceptPlugins
+class TorManager(object):
     def __init__(self, fileserver_ip=None, fileserver_port=None):
         self.privatekeys = {}  # Onion: Privatekey
         self.site_onions = {}  # Site address: Onion
@@ -58,7 +60,7 @@ class TorManager:
                 assert self.connect(), "No connection"
                 self.log.debug("Tor proxy port %s check ok" % config.tor_proxy)
             except Exception, err:
-                self.log.debug("Tor proxy port %s check error: %s" % (config.tor_proxy, err))
+                self.log.info("Starting self-bundled Tor, due to Tor proxy port %s check error: %s" % (config.tor_proxy, err))
                 self.enabled = False
                 # Change to self-bundled Tor ports
                 from lib.PySocks import socks
@@ -148,12 +150,15 @@ class TorManager:
         self.site_onions = {}
         self.privatekeys = {}
 
+        return self.connectController()
+
+    def connectController(self):
         if "socket_noproxy" in dir(socket):  # Socket proxy-patched, use non-proxy one
             conn = socket.socket_noproxy(socket.AF_INET, socket.SOCK_STREAM)
         else:
             conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
-        self.log.debug("Connecting to %s:%s" % (self.ip, self.port))
+        self.log.info("Connecting to Tor Controller %s:%s" % (self.ip, self.port))
         try:
             with self.lock:
                 conn.connect((self.ip, self.port))
@@ -203,19 +208,28 @@ class TorManager:
             self.log.error("Tor reset circuits error: %s" % res)
 
     def addOnion(self):
+        result = self.makeOnionAndKey()
+        if result:
+            onion_address, onion_privatekey = result
+            self.privatekeys[onion_address] = onion_privatekey
+            self.status = u"OK (%s onions running)" % len(self.privatekeys)
+            SiteManager.peer_blacklist.append((onion_address + ".onion", self.fileserver_port))
+            return onion_address
+        else:
+            return False
+
+    def makeOnionAndKey(self):
         res = self.request("ADD_ONION NEW:RSA1024 port=%s" % self.fileserver_port)
         match = re.search("ServiceID=([A-Za-z0-9]+).*PrivateKey=RSA1024:(.*?)[\r\n]", res, re.DOTALL)
         if match:
             onion_address, onion_privatekey = match.groups()
-            self.privatekeys[onion_address] = onion_privatekey
-            self.status = u"OK (%s onion running)" % len(self.privatekeys)
-            SiteManager.peer_blacklist.append((onion_address + ".onion", self.fileserver_port))
-            return onion_address
+            return (onion_address, onion_privatekey)
         else:
             self.status = u"AddOnion error (%s)" % res
             self.log.error("Tor addOnion error: %s" % res)
             return False
 
+
     def delOnion(self, address):
         res = self.request("DEL_ONION %s" % address)
         if "250 OK" in res:

From ce4a91b6790f5caa7090afc3d055b9b422dcd875 Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Fri, 17 Feb 2017 01:23:05 +0000
Subject: [PATCH 02/10] Create __init__.py

---
 plugins/disabled-StemPort/__init__.py | 10 ++++++++++
 1 file changed, 10 insertions(+)
 create mode 100644 plugins/disabled-StemPort/__init__.py

diff --git a/plugins/disabled-StemPort/__init__.py b/plugins/disabled-StemPort/__init__.py
new file mode 100644
index 00000000..1ce4d973
--- /dev/null
+++ b/plugins/disabled-StemPort/__init__.py
@@ -0,0 +1,10 @@
+try:
+    from stem.control import Controller
+    stem_found = True
+except Exception, err:
+    print "STEM NOT FOUND! %s" % err
+    stem_found = False
+
+if stem_found:
+    print "Starting Stem plugin..."
+    import StemPortPlugin

From 8ba684e8c35de26ed3774bc9cb95fdf8395fb82e Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Fri, 17 Feb 2017 01:26:11 +0000
Subject: [PATCH 03/10] Create StemPortPlugin.py

---
 plugins/disabled-StemPort/StemPortPlugin.py | 129 ++++++++++++++++++++
 1 file changed, 129 insertions(+)
 create mode 100644 plugins/disabled-StemPort/StemPortPlugin.py

diff --git a/plugins/disabled-StemPort/StemPortPlugin.py b/plugins/disabled-StemPort/StemPortPlugin.py
new file mode 100644
index 00000000..f2be9728
--- /dev/null
+++ b/plugins/disabled-StemPort/StemPortPlugin.py
@@ -0,0 +1,129 @@
+import logging
+import traceback
+
+import socket
+import stem
+from stem import Signal
+from stem.control import Controller
+from stem.socket import ControlPort
+
+from Plugin import PluginManager
+from Config import config
+from Debug import Debug
+
+class PatchedControlPort(ControlPort):
+    def _make_socket(self):
+        try:
+            if "socket_noproxy" in dir(socket):  # Socket proxy-patched, use non-proxy one
+                control_socket = socket.socket_noproxy(socket.AF_INET, socket.SOCK_STREAM)
+            else:
+                control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+
+            # TODO: repeated code - consider making a separate method
+
+            control_socket.connect((self._control_addr, self._control_port))
+            return control_socket
+        except socket.error as exc:
+            raise stem.SocketError(exc)
+
+def from_port(address = '127.0.0.1', port = 'default'):
+    import stem.connection
+
+    if not stem.util.connection.is_valid_ipv4_address(address):
+        raise ValueError('Invalid IP address: %s' % address)
+    elif port != 'default' and not stem.util.connection.is_valid_port(port):
+        raise ValueError('Invalid port: %s' % port)
+
+    if port == 'default':
+        raise ValueError('Must specify a port')
+    else:
+        control_port = PatchedControlPort(address, port)
+
+    return Controller(control_port)
+
+
+@PluginManager.registerTo("TorManager")
+class TorManagerPlugin(object):
+
+    def connectController(self):
+        self.log.info("Authenticate using Stem... %s:%s" % (self.ip, self.port))
+
+        try:
+            with self.lock:
+                if config.tor_password:
+                    controller = from_port(port=self.port, password=config.tor_password)
+                else:
+                    controller = from_port(port=self.port)
+                controller.authenticate()
+                self.controller = controller
+                self.status = u"Connected via Stem"
+        except Exception, err:
+            print("\n")
+            traceback.print_exc()
+            print("\n")
+
+            self.controller = None
+            self.status = u"Error (%s)" % err
+            self.log.error("Tor stem connect error: %s" % Debug.formatException(err))
+
+        return self.controller
+
+
+    def disconnect(self):
+        self.controller.close()
+        self.controller = None
+
+
+    def resetCircuits(self):
+        try:
+            self.controller.signal(Signal.NEWNYM)
+        except Exception, err:
+            self.status = u"Stem reset circuits error (%s)" % err
+            self.log.error("Stem reset circuits error: %s" % err)
+
+
+    def makeOnionAndKey(self):
+        try:
+            service = self.controller.create_ephemeral_hidden_service(
+                {self.fileserver_port: self.fileserver_port},
+                await_publication = True
+            )
+            if service.private_key_type != "RSA1024":
+                raise Exception("ZeroNet doesn't support crypto " + service.private_key_type)
+            return (service.service_id, service.private_key)
+
+        except Exception, err:
+            self.status = u"AddOnion error (stem)"
+            self.log.error("Failed to create hidden service with Stem: " + err)
+            return False
+
+
+    def delOnion(self, address):
+        try:
+            self.controller.remove_ephemeral_hidden_service(address)
+            return True
+        except Exception, err:
+            self.status = u"DelOnion error (stem)"
+            self.log.error("Stem delOnion error: %s" % err)
+            self.disconnect() # Why?
+            return False
+
+
+    def request(self, cmd):
+        with self.lock:
+            if not self.enabled:
+                return False
+            else:
+                self.log.debug("[WARNING] StemPort self.request should not be called")
+                return ""
+
+    def send(self, cmd, conn=None):
+        self.log.debug("[WARNING] StemPort self.send should not be called")
+        return ""
+
+    def createSocket(self, onion, port):
+        if not self.enabled:
+            return False
+
+        self.debug.log("[WARNING] StemPort createSocket should not be called")
+        return False

From ccf2897a65b8262c138c0e68ba77c8f73dcae764 Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Fri, 17 Feb 2017 22:25:44 +0000
Subject: [PATCH 04/10] Update StemPortPlugin.py

---
 plugins/disabled-StemPort/StemPortPlugin.py | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/plugins/disabled-StemPort/StemPortPlugin.py b/plugins/disabled-StemPort/StemPortPlugin.py
index f2be9728..d7aaecd9 100644
--- a/plugins/disabled-StemPort/StemPortPlugin.py
+++ b/plugins/disabled-StemPort/StemPortPlugin.py
@@ -11,6 +11,10 @@ from Plugin import PluginManager
 from Config import config
 from Debug import Debug
 
+from gevent import monkey
+monkey.patch_all()
+print "Patched..."
+
 class PatchedControlPort(ControlPort):
     def _make_socket(self):
         try:
@@ -56,7 +60,7 @@ class TorManagerPlugin(object):
                     controller = from_port(port=self.port)
                 controller.authenticate()
                 self.controller = controller
-                self.status = u"Connected via Stem"
+                self.status = u"Connected (via Stem)"
         except Exception, err:
             print("\n")
             traceback.print_exc()
@@ -86,10 +90,14 @@ class TorManagerPlugin(object):
         try:
             service = self.controller.create_ephemeral_hidden_service(
                 {self.fileserver_port: self.fileserver_port},
-                await_publication = True
+                await_publication = False
             )
             if service.private_key_type != "RSA1024":
                 raise Exception("ZeroNet doesn't support crypto " + service.private_key_type)
+
+            self.log.info("Stem created onion service %s.onion" % service.service_id)
+            self.log.info("It takes a few seconds for this onion service to be recognized by HSDirs.")
+            
             return (service.service_id, service.private_key)
 
         except Exception, err:

From 92b9397ee279056ab5e04dc6663e60984af5210a Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Tue, 21 Feb 2017 01:45:19 +0000
Subject: [PATCH 05/10] Update StemPortPlugin.py - Patch conservatively

---
 plugins/disabled-StemPort/StemPortPlugin.py | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/plugins/disabled-StemPort/StemPortPlugin.py b/plugins/disabled-StemPort/StemPortPlugin.py
index d7aaecd9..afb65cde 100644
--- a/plugins/disabled-StemPort/StemPortPlugin.py
+++ b/plugins/disabled-StemPort/StemPortPlugin.py
@@ -12,8 +12,10 @@ from Config import config
 from Debug import Debug
 
 from gevent import monkey
-monkey.patch_all()
-print "Patched..."
+monkey.patch_time()
+monkey.patch_socket(dns=False)
+monkey.patch_thread()
+print "Stem Port Plugin: modules are patched"
 
 class PatchedControlPort(ControlPort):
     def _make_socket(self):
@@ -95,9 +97,8 @@ class TorManagerPlugin(object):
             if service.private_key_type != "RSA1024":
                 raise Exception("ZeroNet doesn't support crypto " + service.private_key_type)
 
-            self.log.info("Stem created onion service %s.onion" % service.service_id)
-            self.log.info("It takes a few seconds for this onion service to be recognized by HSDirs.")
-            
+            self.log.info("Stem created %s.onion (async descriptor publication)" % service.service_id)
+
             return (service.service_id, service.private_key)
 
         except Exception, err:

From 2e4767926c83d32c85152db254a204a479ffe1bf Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Thu, 23 Feb 2017 22:47:32 +0000
Subject: [PATCH 06/10] Update StemPortPlugin.py - check config.tor

---
 plugins/disabled-StemPort/StemPortPlugin.py | 22 ++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/plugins/disabled-StemPort/StemPortPlugin.py b/plugins/disabled-StemPort/StemPortPlugin.py
index afb65cde..733503b6 100644
--- a/plugins/disabled-StemPort/StemPortPlugin.py
+++ b/plugins/disabled-StemPort/StemPortPlugin.py
@@ -11,11 +11,15 @@ from Plugin import PluginManager
 from Config import config
 from Debug import Debug
 
-from gevent import monkey
-monkey.patch_time()
-monkey.patch_socket(dns=False)
-monkey.patch_thread()
-print "Stem Port Plugin: modules are patched"
+if config.tor != "disable":
+    from gevent import monkey
+    monkey.patch_time()
+    monkey.patch_socket(dns=False)
+    monkey.patch_thread()
+    print "Stem Port Plugin: modules are patched."
+else:
+    print "Stem Port Plugin: Tor mode disabled. Module patching skipped."
+
 
 class PatchedControlPort(ControlPort):
     def _make_socket(self):
@@ -97,7 +101,7 @@ class TorManagerPlugin(object):
             if service.private_key_type != "RSA1024":
                 raise Exception("ZeroNet doesn't support crypto " + service.private_key_type)
 
-            self.log.info("Stem created %s.onion (async descriptor publication)" % service.service_id)
+            self.log.debug("Stem created %s.onion (async descriptor publication)" % service.service_id)
 
             return (service.service_id, service.private_key)
 
@@ -123,16 +127,16 @@ class TorManagerPlugin(object):
             if not self.enabled:
                 return False
             else:
-                self.log.debug("[WARNING] StemPort self.request should not be called")
+                self.log.error("[WARNING] StemPort self.request should not be called")
                 return ""
 
     def send(self, cmd, conn=None):
-        self.log.debug("[WARNING] StemPort self.send should not be called")
+        self.log.error("[WARNING] StemPort self.send should not be called")
         return ""
 
     def createSocket(self, onion, port):
         if not self.enabled:
             return False
 
-        self.debug.log("[WARNING] StemPort createSocket should not be called")
+        self.log.error("[WARNING] StemPort createSocket should not be called")
         return False

From ad900479f6adede20459d4e4cf6dd881db3d670a Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Thu, 23 Feb 2017 23:08:56 +0000
Subject: [PATCH 07/10] Important Update - Don't override createSocket

---
 plugins/disabled-StemPort/StemPortPlugin.py | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/plugins/disabled-StemPort/StemPortPlugin.py b/plugins/disabled-StemPort/StemPortPlugin.py
index 733503b6..ed4a25a9 100644
--- a/plugins/disabled-StemPort/StemPortPlugin.py
+++ b/plugins/disabled-StemPort/StemPortPlugin.py
@@ -133,10 +133,3 @@ class TorManagerPlugin(object):
     def send(self, cmd, conn=None):
         self.log.error("[WARNING] StemPort self.send should not be called")
         return ""
-
-    def createSocket(self, onion, port):
-        if not self.enabled:
-            return False
-
-        self.log.error("[WARNING] StemPort createSocket should not be called")
-        return False

From a724dd472f4e7654f497b571d394039c863ed281 Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Thu, 23 Feb 2017 23:09:47 +0000
Subject: [PATCH 08/10] Update TorManager.py

---
 src/Tor/TorManager.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/Tor/TorManager.py b/src/Tor/TorManager.py
index c998570a..0347acad 100644
--- a/src/Tor/TorManager.py
+++ b/src/Tor/TorManager.py
@@ -292,11 +292,13 @@ class TorManager(object):
                 self.log.debug("Created new hidden service for %s: %s" % (site_address, onion))
             return onion
 
+    # Creates and returns a
+    # socket that has conencted to the Tor Network
     def createSocket(self, onion, port):
         if not self.enabled:
             return False
-        self.log.debug("Creating new socket to %s:%s" % (onion, port))
-        if config.tor == "always":  # Every socket is proxied by default
+        self.log.debug("Creating new Tor socket to %s:%s" % (onion, port))
+        if config.tor == "always":  # Every socket is proxied by default, in this mode
             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             sock.connect((onion, int(port)))
         else:

From 048207f70b19848cf32d60cd073e990ef5880861 Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Thu, 23 Feb 2017 23:39:05 +0000
Subject: [PATCH 09/10] Update StemPortPlugin.py

---
 plugins/disabled-StemPort/StemPortPlugin.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/plugins/disabled-StemPort/StemPortPlugin.py b/plugins/disabled-StemPort/StemPortPlugin.py
index ed4a25a9..3a3787c7 100644
--- a/plugins/disabled-StemPort/StemPortPlugin.py
+++ b/plugins/disabled-StemPort/StemPortPlugin.py
@@ -106,7 +106,7 @@ class TorManagerPlugin(object):
             return (service.service_id, service.private_key)
 
         except Exception, err:
-            self.status = u"AddOnion error (stem)"
+            self.status = u"AddOnion error (Stem: %s)" % err
             self.log.error("Failed to create hidden service with Stem: " + err)
             return False
 
@@ -116,8 +116,8 @@ class TorManagerPlugin(object):
             self.controller.remove_ephemeral_hidden_service(address)
             return True
         except Exception, err:
-            self.status = u"DelOnion error (stem)"
-            self.log.error("Stem delOnion error: %s" % err)
+            self.status = u"DelOnion error (Stem: %s)" % err
+            self.log.error("Stem failed to delete %s.onion: %s" % (address, err))
             self.disconnect() # Why?
             return False
 

From 0aa635893874c45f02018661be847acb881cedd6 Mon Sep 17 00:00:00 2001
From: MuxZeroNet <MuxZeroNet@users.noreply.github.com>
Date: Thu, 23 Feb 2017 23:39:45 +0000
Subject: [PATCH 10/10] Update TorManager.py

---
 src/Tor/TorManager.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/Tor/TorManager.py b/src/Tor/TorManager.py
index 0347acad..9f2b1801 100644
--- a/src/Tor/TorManager.py
+++ b/src/Tor/TorManager.py
@@ -293,7 +293,7 @@ class TorManager(object):
             return onion
 
     # Creates and returns a
-    # socket that has conencted to the Tor Network
+    # socket that has connected to the Tor Network
     def createSocket(self, onion, port):
         if not self.enabled:
             return False