예제 #1
0
    def __init__(self, control=None):
        self.config = {}
        '''Current configuration, by keys.'''

        if control is None:
            self.protocol = None
            self.__dict__['_slutty_'] = None
            self.__dict__['config']['HiddenServices'] = _ListWrapper([], functools.partial(self.mark_unsaved, 'HiddenServices'))

        else:
            self.protocol = ITorControlProtocol(control)

        self.unsaved = {}
        '''Configuration that has been changed since last save().'''

        self.parsers = {}
        '''Instances of the parser classes, subclasses of TorConfigType'''

        self.post_bootstrap = defer.Deferred()
        if self.protocol:
            if self.protocol.post_bootstrap:
                self.protocol.post_bootstrap.addCallback(self.bootstrap).addErrback(log.err)
            else:
                self.bootstrap()

        else:
            self.post_bootstrap.callback(self)

        self.__dict__['_setup_'] = None
예제 #2
0
    def __init__(self, control, errback=None):
        self._setup = False
        self.attrs = {}
        '''After _setup is True, these are all we show as attributes.'''

        self.protocol = ITorControlProtocol(control)
        self.errback = errback

        self.post_bootstrap = defer.Deferred()
        if self.protocol.post_bootstrap:
            self.protocol.post_bootstrap.addCallback(self.bootstrap)

        else:
            self.bootstrap()
예제 #3
0
    def __init__(self, control=None):
        self.config = {}
        '''Current configuration, by keys.'''

        if control is None:
            self._protocol = None
            self.__dict__['_accept_all_'] = None

        else:
            self._protocol = ITorControlProtocol(control)

        self.unsaved = OrderedDict()
        '''Configuration that has been changed since last save().'''

        self.parsers = {}
        '''Instances of the parser classes, subclasses of TorConfigType'''

        self.list_parsers = set(['hiddenservices'])
        '''All the names (keys from .parsers) that are a List of something.'''

        # during bootstrapping we decide whether we support the
        # following features. A thing goes in here if TorConfig
        # behaves differently depending upon whether it shows up in
        # "GETINFO config/names"
        self._supports = dict(
            HiddenServiceDirGroupReadable=False
        )
        self._defaults = dict()

        self.post_bootstrap = defer.Deferred()
        if self.protocol:
            if self.protocol.post_bootstrap:
                self.protocol.post_bootstrap.addCallback(
                    self.bootstrap).addErrback(self.post_bootstrap.errback)
            else:
                self.bootstrap()

        else:
            self.do_post_bootstrap(self)

        self.__dict__['_setup_'] = None
예제 #4
0
    def __init__(self, protocol, bootstrap=True):
        self.protocol = ITorControlProtocol(protocol)
        # fixme could use protocol.on_disconnect to re-connect; see issue #3

        # could override these to get your own Circuit/Stream subclasses
        # to track these things
        self.circuit_factory = Circuit
        self.stream_factory = Stream

        self._attacher = None
        """If set, provides
        :class:`txtorcon.interface.IStreamAttacher` to attach new
        streams we hear about."""

        self.tor_binary = 'tor'

        self.circuit_listeners = []
        self.stream_listeners = []

        self.addrmap = AddrMap()
        #: keys on id (integer)
        self.circuits = {}

        #: keys on id (integer)
        self.streams = {}

        #: list of unique routers
        self.all_routers = set()

        #: keys by hexid (string) and by unique names
        self.routers = {}
        self._old_routers = {}

        #: keys on name, value always list (many duplicate "Unnamed"
        #: routers, for example)
        self.routers_by_name = {}

        #: keys by hexid (string)
        self.routers_by_hash = {}

        #: potentially-usable as entry guards, I think? (any router
        #: with 'Guard' flag)
        self.guards = {}

        #: from GETINFO entry-guards, our current entry guards
        self.entry_guards = {}

        #: list of entry guards we didn't parse out
        self.unusable_entry_guards = []

        #: keys by name
        self.authorities = {}

        #: see set_attacher
        self._cleanup = None

        self._network_status_parser = MicrodescriptorParser(
            self._create_router)

        self.post_bootstrap = defer.Deferred()
        if bootstrap:
            self.protocol.post_bootstrap.addCallback(self._bootstrap)
            self.protocol.post_bootstrap.addErrback(
                self.post_bootstrap.errback)
예제 #5
0
    def __init__(self, protocol, bootstrap=True, write_state_diagram=False):
        self.protocol = ITorControlProtocol(protocol)
        ## fixme could use protocol.on_disconnect to re-connect; see issue #3

        ## could override these to get your own Circuit/Stream subclasses
        ## to track these things
        self.circuit_factory = Circuit
        self.stream_factory = Stream

        self.attacher = None
        """If set, provides
        :class:`txtorcon.interface.IStreamAttacher` to attach new
        streams we hear about."""

        self.tor_binary = 'tor'

        self.circuit_listeners = []
        self.stream_listeners = []

        self.addrmap = AddrMap()
        self.circuits = {}  # keys on id (integer)
        self.streams = {}  # keys on id (integer)

        self.routers = {}  # keys by hexid (string) and by unique names
        self.routers_by_name = {
        }  # keys on name, value always list (many duplicate "Unnamed" routers, for example)
        self.guards = {
        }  # potentially-usable as entry guards, I think? (any router with 'Guard' flag)
        self.entry_guards = {
        }  # from GETINFO entry-guards, our current entry guards
        self.unusable_entry_guards = [
        ]  # list of entry guards we didn't parse out
        self.authorities = {}  # keys by name

        self.cleanup = None  # see set_attacher

        class die(object):
            __name__ = 'die'  # FIXME? just to ease spagetti.py:82's pain

            def __init__(self, msg):
                self.msg = msg

            def __call__(self, *args):
                raise RuntimeError(self.msg % tuple(args))

        def nothing(*args):
            pass

        waiting_r = State("waiting_r")
        waiting_w = State("waiting_w")
        waiting_p = State("waiting_p")
        waiting_s = State("waiting_s")

        def ignorable_line(x):
            return x.strip() == '.' or x.strip(
            ) == 'OK' or x[:3] == 'ns/' or x.strip() == ''

        waiting_r.add_transition(Transition(waiting_r, ignorable_line,
                                            nothing))
        waiting_r.add_transition(
            Transition(waiting_s, lambda x: x[:2] == 'r ', self._router_begin))
        ## FIXME use better method/func than die!!
        waiting_r.add_transition(
            Transition(waiting_r, lambda x: x[:2] != 'r ',
                       die('Expected "r " while parsing routers not "%s"')))

        waiting_s.add_transition(
            Transition(waiting_w, lambda x: x[:2] == 's ', self._router_flags))
        waiting_s.add_transition(
            Transition(waiting_s, lambda x: x[:2] == 'a ',
                       self._router_address))
        waiting_s.add_transition(Transition(waiting_r, ignorable_line,
                                            nothing))
        waiting_s.add_transition(
            Transition(waiting_r, lambda x: x[:2] != 's ' and x[:2] != 'a ',
                       die('Expected "s " while parsing routers not "%s"')))
        waiting_s.add_transition(
            Transition(waiting_r, lambda x: x.strip() == '.', nothing))

        waiting_w.add_transition(
            Transition(waiting_p, lambda x: x[:2] == 'w ',
                       self._router_bandwidth))
        waiting_w.add_transition(Transition(waiting_r, ignorable_line,
                                            nothing))
        waiting_w.add_transition(
            Transition(waiting_s, lambda x: x[:2] == 'r ',
                       self._router_begin))  # "w" lines are optional
        waiting_w.add_transition(
            Transition(waiting_r, lambda x: x[:2] != 'w ',
                       die('Expected "w " while parsing routers not "%s"')))
        waiting_w.add_transition(
            Transition(waiting_r, lambda x: x.strip() == '.', nothing))

        waiting_p.add_transition(
            Transition(waiting_r, lambda x: x[:2] == 'p ',
                       self._router_policy))
        waiting_p.add_transition(Transition(waiting_r, ignorable_line,
                                            nothing))
        waiting_p.add_transition(
            Transition(waiting_s, lambda x: x[:2] == 'r ',
                       self._router_begin))  # "p" lines are optional
        waiting_p.add_transition(
            Transition(waiting_r, lambda x: x[:2] != 'p ',
                       die('Expected "p " while parsing routers not "%s"')))
        waiting_p.add_transition(
            Transition(waiting_r, lambda x: x.strip() == '.', nothing))

        self._network_status_parser = FSM(
            [waiting_r, waiting_s, waiting_w, waiting_p])
        if write_state_diagram:
            with open('routerfsm.dot', 'w') as fsmfile:
                fsmfile.write(self._network_status_parser.dotty())

        self.post_bootstrap = defer.Deferred()
        if bootstrap:
            if self.protocol.post_bootstrap:
                self.protocol.post_bootstrap.addCallback(
                    self._bootstrap).addErrback(self.post_bootstrap.errback)
            else:
                self._bootstrap()