Dumb tor configurator using stem
This commit is contained in:
parent
ec11632297
commit
53d77ce911
111
src/plugins/proxyconfig_stem.py
Normal file
111
src/plugins/proxyconfig_stem.py
Normal file
|
@ -0,0 +1,111 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import logging
|
||||
import random # noseq
|
||||
import tempfile
|
||||
|
||||
import stem
|
||||
import stem.control
|
||||
import stem.process
|
||||
|
||||
|
||||
class DebugLogger(object):
|
||||
"""Safe logger wrapper for tor and plugin's logs"""
|
||||
# pylint: disable=too-few-public-methods
|
||||
def __init__(self):
|
||||
self._logger = logging.getLogger(__name__.split('.', 1)[0])
|
||||
self._levels = {
|
||||
'err': 40,
|
||||
'warn': 30,
|
||||
'notice': 20
|
||||
}
|
||||
|
||||
def __call__(self, line):
|
||||
try:
|
||||
level, line = line.split('[', 1)[1].split(']')
|
||||
except IndexError:
|
||||
# Plugin's debug or unexpected log line from tor
|
||||
self._logger.debug(line)
|
||||
else:
|
||||
self._logger.log(self._levels.get(level, 10), '(tor)' + line)
|
||||
|
||||
|
||||
def connect_plugin(config):
|
||||
"""Run stem proxy configurator"""
|
||||
logwrite = DebugLogger()
|
||||
if config.safeGet('bitmessagesettings', 'sockshostname') not in (
|
||||
'localhost', '127.0.0.1', ''
|
||||
):
|
||||
# remote proxy is choosen for outbound connections,
|
||||
# nothing to do here, but need to set socksproxytype to SOCKS5!
|
||||
logwrite(
|
||||
'sockshostname is set to remote address,'
|
||||
' aborting stem proxy configuration')
|
||||
return
|
||||
|
||||
datadir = tempfile.mkdtemp()
|
||||
control_socket = os.path.join(datadir, 'control')
|
||||
tor_config = {
|
||||
'SocksPort': '9050',
|
||||
# 'DataDirectory': datadir, # had an exception with control socket
|
||||
'ControlSocket': control_socket
|
||||
}
|
||||
port = config.safeGet('bitmessagesettings', 'socksport', '9050')
|
||||
for attempt in range(50):
|
||||
if attempt > 0:
|
||||
port = random.randint(32767, 65535)
|
||||
tor_config['SocksPort'] = str(port)
|
||||
# It's recommended to use separate tor instance for hidden services.
|
||||
# So if there is a system wide tor, use it for outbound connections.
|
||||
try:
|
||||
stem.process.launch_tor_with_config(
|
||||
tor_config, take_ownership=True, init_msg_handler=logwrite)
|
||||
except OSError:
|
||||
continue
|
||||
else:
|
||||
logwrite('Started tor on port %s' % port)
|
||||
break
|
||||
|
||||
if config.safeGetBoolean('bitmessagesettings', 'sockslisten'):
|
||||
# need a hidden service for inbound connections
|
||||
try:
|
||||
controller = stem.control.Controller.from_socket_file(
|
||||
control_socket)
|
||||
controller.authenticate()
|
||||
except stem.SocketError:
|
||||
# something goes wrong way
|
||||
logwrite('Failed to instantiate or authenticate on controller')
|
||||
return
|
||||
|
||||
onionhostname = config.safeGet('bitmessagesettings', 'onionhostname')
|
||||
onionkey = config.safeGet(onionhostname, 'privsigningkey')
|
||||
if onionhostname and not onionkey:
|
||||
logwrite('The hidden service found in config ): %s' % onionhostname)
|
||||
onionkeytype = config.safeGet(onionhostname, 'keytype')
|
||||
|
||||
response = controller.create_ephemeral_hidden_service(
|
||||
config.safeGetInt('bitmessagesettings', 'onionport', 8444),
|
||||
key_type=(onionkeytype or 'NEW'),
|
||||
key_content=(onionkey or 'BEST')
|
||||
)
|
||||
|
||||
if not response.is_ok():
|
||||
logwrite('Bad response from controller ):')
|
||||
return
|
||||
|
||||
if not onionkey:
|
||||
if not onionhostname:
|
||||
onionhostname = response.service_id + '.onion'
|
||||
config.set(
|
||||
'bitmessagesettings', 'onionhostname', onionhostname)
|
||||
else:
|
||||
onionhostname = response.service_id + '.onion'
|
||||
logwrite('Started hidden service %s' % onionhostname)
|
||||
config.add_section(onionhostname)
|
||||
config.set(
|
||||
onionhostname, 'privsigningkey', response.private_key)
|
||||
config.set(
|
||||
onionhostname, 'keytype', response.private_key_type)
|
||||
config.save()
|
||||
config.set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
|
Reference in New Issue
Block a user