[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [nyx/master] Nyx tor interpreter now uses Stem's tor interpretor methods
commit 89e9ff7f8af12a3f9b5c4d6ad553825ecf8d281a
Author: Sambuddha Basu <sambuddhabasu1@xxxxxxxxx>
Date: Sat Jun 25 00:36:06 2016 -0700
Nyx tor interpreter now uses Stem's tor interpretor methods
---
nyx/panel/interpreter.py | 56 ++++++---
nyx/tor_interpreter.py | 310 -----------------------------------------------
2 files changed, 39 insertions(+), 327 deletions(-)
diff --git a/nyx/panel/interpreter.py b/nyx/panel/interpreter.py
index 0c5d8c6..85efb02 100644
--- a/nyx/panel/interpreter.py
+++ b/nyx/panel/interpreter.py
@@ -5,14 +5,20 @@ information, tab completion, and other usability features.
import nyx.controller
import nyx.curses
+import re
-from nyx.curses import GREEN, CYAN, BOLD, HIGHLIGHT
+from nyx.curses import BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, BOLD, HIGHLIGHT, NORMAL
from nyx import panel, tor_interpreter
+import stem.connection
+import stem.interpreter.commands
-USAGE_INFO = "to use this panel press enter"
-PROMPT = ">>> "
+
+USAGE_INFO = 'to use this panel press enter'
+PROMPT = '>>> '
PROMPT_LINE = [[(PROMPT, GREEN, BOLD), (USAGE_INFO, CYAN, BOLD)]]
+ANSI_RE = re.compile("\\x1b\[([0-9;]*)m")
+ATTRS = {"0": NORMAL, "1": BOLD, "30": BLACK, "31": RED, "32": GREEN, "33": YELLOW, "34": BLUE, "35": MAGENTA, "36": CYAN}
class InterpreterPanel(panel.Panel):
"""
@@ -24,7 +30,12 @@ class InterpreterPanel(panel.Panel):
panel.Panel.__init__(self, 'interpreter')
self._is_input_mode = False
- self.interpreter = tor_interpreter.ControlInterpreter()
+ self.controller = stem.connection.connect(
+ control_port = ('127.0.0.1', 'default'),
+ control_socket = '/var/run/tor/control',
+ password_prompt = True,
+ )
+ self.interpreter = stem.interpreter.commands.ControlInterpretor(self.controller)
def key_handlers(self):
def _execute_command():
@@ -37,15 +48,21 @@ class InterpreterPanel(panel.Panel):
if not user_input:
is_done = True
- else:
- try:
- input_entry, output_entry = self.interpreter.handle_query(user_input)
- input_entry.insert(0, (PROMPT, GREEN, BOLD))
- PROMPT_LINE.insert(len(PROMPT_LINE) - 1, input_entry)
- for line in output_entry:
- PROMPT_LINE.insert(len(PROMPT_LINE) - 1, line)
- except tor_interpreter.InterpreterClosed:
- is_done = True
+
+ response = self.interpreter.run_command(user_input)
+ color = None
+ if response:
+ PROMPT_LINE.insert(len(PROMPT_LINE) - 1, [(PROMPT, GREEN, BOLD), (user_input)])
+ attrs = []
+ for line in response.split('\n'):
+ new_attrs = []
+ ansi_re = ANSI_RE.findall(line)
+ if line.find("\x1b[") == 0 and ansi_re:
+ for attr in ansi_re[0].split(';'):
+ new_attrs.append(ATTRS[attr])
+ attrs = new_attrs
+ line = ANSI_RE.sub('', line)
+ PROMPT_LINE.insert(len(PROMPT_LINE) - 1, [(line, ) + tuple(attrs)])
if is_done:
self._is_input_mode = False
@@ -56,7 +73,7 @@ class InterpreterPanel(panel.Panel):
)
def draw(self, width, height):
- usage_msg = " (enter \"/help\" for usage or a blank line to stop)" if self._is_input_mode else ""
+ usage_msg = ' (enter \"/help\" for usage or a blank line to stop)' if self._is_input_mode else ""
self.addstr(0, 0, 'Control Interpreter%s:' % usage_msg, HIGHLIGHT)
x_offset = 0
@@ -64,12 +81,17 @@ class InterpreterPanel(panel.Panel):
for entry in PROMPT_LINE:
cursor = x_offset
- msg, color, attr = None, None, None
for line in entry:
- if len(line) == 2:
+ if len(line) == 1:
+ self.addstr(draw_line, cursor, line[0])
+ elif len(line) == 2:
self.addstr(draw_line, cursor, line[0], line[1])
elif len(line) == 3:
self.addstr(draw_line, cursor, line[0], line[1], line[2])
- cursor += len(line[0])
+ self.addstr(draw_line, cursor, line)
+ try:
+ cursor += len(line[0])
+ except:
+ pass
draw_line += 1
diff --git a/nyx/tor_interpreter.py b/nyx/tor_interpreter.py
deleted file mode 100644
index 7b59a36..0000000
--- a/nyx/tor_interpreter.py
+++ /dev/null
@@ -1,310 +0,0 @@
-from nyx.curses import GREEN, CYAN, RED, MAGENTA, BLUE, BOLD, HIGHLIGHT
-from nyx import tor_controller
-
-
-# initial location /write will save to when no path is specified
-DEFAULT_WRITE_PATH = "/tmp/torInterpretor_output"
-
-MULTILINE_UNIMPLEMENTED_NOTICE = "Multi-line control options like this are not yet implemented."
-
-GENERAL_HELP = """Interpretor commands include:
- /help - provides information for interpretor and tor commands/config options
- /info - general information for a relay
- /find - searches backlog for lines with the given regex
- /events - prints events that we've received
- /write - saves backlog to a given location
- /quit - shuts down the interpretor
-
-Tor commands include:
- GETINFO - queries information from tor
- GETCONF, SETCONF, RESETCONF - show or edit a configuration option
- SIGNAL - issues control signal to the process (for resetting, stopping, etc)
- SETEVENTS - configures the events tor will notify us of
-
- USEFEATURE - enables custom behavior for the controller
- SAVECONF - writes tor's current configuration to our torrc
- LOADCONF - loads the given input like it was part of our torrc
- MAPADDRESS - replaces requests for one address with another
- POSTDESCRIPTOR - adds a relay descriptor to our cache
- EXTENDCIRCUIT - create or extend a tor circuit
- SETCIRCUITPURPOSE - configures the purpose associated with a circuit
- CLOSECIRCUIT - closes the given circuit
- ATTACHSTREAM - associates an application's stream with a tor circuit
- REDIRECTSTREAM - sets a stream's destination
- CLOSESTREAM - closes the given stream
- RESOLVE - issues an asynchronous dns or rdns request over tor
- TAKEOWNERSHIP - instructs tor to quit when this control connection is closed
- PROTOCOLINFO - queries version and controller authentication information
- QUIT - disconnect the control connection
-
-For more information use '/help [OPTION]'."""
-
-HELP_HELP = """Provides usage information for the given interpretor, tor command, or tor
-configuration option.
-
-Example:
- /help info # provides a description of the '/info' option
- /help GETINFO # usage information for tor's GETINFO controller option
- /help ExitPolicy # description of tor's ExitPolicy configuration option"""
-
-HELP_WRITE = """Writes the interpretor's backlog to the given path. If no location is
-specified then this saves to the last path specified (initially '%s').""" % DEFAULT_WRITE_PATH
-
-HELP_EVENTS = """Provides events that we've received belonging to the given event types. If
-no types are specified then this provides all the messages that we've
-received."""
-
-HELP_INFO = """Provides general information for a relay that's currently in the consensus.
-If no relay is specified then this provides information on ourselves."""
-
-HELP_FIND = """Searches the backlog for lines matching a given regular expression pattern.
-Results are deduplicated and the matching portions bolded."""
-
-HELP_QUIT = """Terminates the interpretor."""
-
-HELP_GETINFO = """Queries the tor process for information. Options are...
-"""
-
-HELP_GETCONF = """Provides the current value for a given configuration value. Options include...
-"""
-
-HELP_SETCONF = """Sets the given configuration parameters. Values can be quoted or non-quoted
-strings, and reverts the option to 0 or NULL if not provided.
-
-Examples:
- * Sets a contact address and resets our family to NULL
- SETCONF MyFamily ContactInfo=foo@xxxxxxx
-
- * Sets an exit policy that only includes port 80/443
- SETCONF ExitPolicy=\"accept *:80, accept *:443, reject *:*\""""
-
-HELP_RESETCONF = """Reverts the given configuration options to their default values. If a value
-is provided then this behaves in the same way as SETCONF.
-
-Examples:
- * Returns both of our accounting parameters to their defaults
- RESETCONF AccountingMax AccountingStart
-
- * Uses the default exit policy and sets our nickname to be 'Goomba'
- RESETCONF ExitPolicy Nickname=Goomba"""
-
-HELP_SIGNAL = """Issues a signal that tells the tor process to reload its torrc, dump its
-stats, halt, etc.
-"""
-
-SIGNAL_DESCRIPTIONS = (
- ("RELOAD / HUP", "reload our torrc"),
- ("SHUTDOWN / INT", "gracefully shut down, waiting 30 seconds if we're a relay"),
- ("DUMP / USR1", "logs information about open connections and circuits"),
- ("DEBUG / USR2", "makes us log at the DEBUG runlevel"),
- ("HALT / TERM", "immediately shut down"),
- ("CLEARDNSCACHE", "clears any cached DNS results"),
- ("NEWNYM", "clears the DNS cache and uses new circuits for future connections")
-)
-
-HELP_SETEVENTS = """Sets the events that we will receive. This turns off any events that aren't
-listed so sending 'SETEVENTS' without any values will turn off all event reporting.
-
-For Tor versions between 0.1.1.9 and 0.2.2.1 adding 'EXTENDED' causes some
-events to give us additional information. After version 0.2.2.1 this is
-always on.
-
-Events include...
-"""
-
-HELP_USEFEATURE = """Customizes the behavior of the control port. Options include...
-"""
-
-HELP_SAVECONF = """Writes Tor's current configuration to its torrc."""
-
-HELP_LOADCONF = """Reads the given text like it belonged to our torrc.
-
-Example:
- +LOADCONF
- # sets our exit policy to just accept ports 80 and 443
- ExitPolicy accept *:80
- ExitPolicy accept *:443
- ExitPolicy reject *:*
- ."""
-
-HELP_MAPADDRESS = """Replaces future requests for one address with another.
-
-Example:
- MAPADDRESS 0.0.0.0=torproject.org 1.2.3.4=tor.freehaven.net"""
-
-HELP_POSTDESCRIPTOR = """Simulates getting a new relay descriptor."""
-
-HELP_EXTENDCIRCUIT = """Extends the given circuit or create a new one if the CircuitID is zero. The
-PATH is a comma separated list of fingerprints. If it isn't set then this
-uses Tor's normal path selection."""
-
-HELP_SETCIRCUITPURPOSE = """Sets the purpose attribute for a circuit."""
-
-HELP_CLOSECIRCUIT = """Closes the given circuit. If "IfUnused" is included then this only closes
-the circuit if it isn't currently being used."""
-
-HELP_ATTACHSTREAM = """Attaches a stream with the given built circuit (tor picks one on its own if
-CircuitID is zero). If HopNum is given then this hop is used to exit the
-circuit, otherwise the last relay is used."""
-
-HELP_REDIRECTSTREAM = """Sets the destination for a given stream. This can only be done after a
-stream is created but before it's attached to a circuit."""
-
-HELP_CLOSESTREAM = """Closes the given stream, the reason being an integer matching a reason as
-per section 6.3 of the tor-spec."""
-
-HELP_RESOLVE = """Performs IPv4 DNS resolution over tor, doing a reverse lookup instead if
-"mode=reverse" is included. This request is processed in the background and
-results in a ADDRMAP event with the response."""
-
-HELP_TAKEOWNERSHIP = """Instructs Tor to gracefully shut down when this control connection is closed."""
-
-HELP_PROTOCOLINFO = """Provides bootstrapping information that a controller might need when first
-starting, like Tor's version and controller authentication. This can be done
-before authenticating to the control port."""
-
-HELP_OPTIONS = {
- "HELP": ("/help [OPTION]", HELP_HELP),
- "WRITE": ("/write [PATH]", HELP_WRITE),
- "EVENTS": ("/events [types]", HELP_EVENTS),
- "INFO": ("/info [relay fingerprint, nickname, or IP address]", HELP_INFO),
- "FIND": ("/find PATTERN", HELP_FIND),
- "QUIT": ("/quit", HELP_QUIT),
- "GETINFO": ("GETINFO OPTION", HELP_GETINFO),
- "GETCONF": ("GETCONF OPTION", HELP_GETCONF),
- "SETCONF": ("SETCONF PARAM[=VALUE]", HELP_SETCONF),
- "RESETCONF": ("RESETCONF PARAM[=VALUE]", HELP_RESETCONF),
- "SIGNAL": ("SIGNAL SIG", HELP_SIGNAL),
- "SETEVENTS": ("SETEVENTS [EXTENDED] [EVENTS]", HELP_SETEVENTS),
- "USEFEATURE": ("USEFEATURE OPTION", HELP_USEFEATURE),
- "SAVECONF": ("SAVECONF", HELP_SAVECONF),
- "LOADCONF": ("LOADCONF...", HELP_LOADCONF),
- "MAPADDRESS": ("MAPADDRESS SOURCE_ADDR=DESTINATION_ADDR", HELP_MAPADDRESS),
- "POSTDESCRIPTOR": ("POSTDESCRIPTOR [purpose=general/controller/bridge] [cache=yes/no]...", HELP_POSTDESCRIPTOR),
- "EXTENDCIRCUIT": ("EXTENDCIRCUIT CircuitID [PATH] [purpose=general/controller]", HELP_EXTENDCIRCUIT),
- "SETCIRCUITPURPOSE": ("SETCIRCUITPURPOSE CircuitID purpose=general/controller", HELP_SETCIRCUITPURPOSE),
- "CLOSECIRCUIT": ("CLOSECIRCUIT CircuitID [IfUnused]", HELP_CLOSECIRCUIT),
- "ATTACHSTREAM": ("ATTACHSTREAM StreamID CircuitID [HOP=HopNum]", HELP_ATTACHSTREAM),
- "REDIRECTSTREAM": ("REDIRECTSTREAM StreamID Address [Port]", HELP_REDIRECTSTREAM),
- "CLOSESTREAM": ("CLOSESTREAM StreamID Reason [Flag]", HELP_CLOSESTREAM),
- "RESOLVE": ("RESOLVE [mode=reverse] address", HELP_RESOLVE),
- "TAKEOWNERSHIP": ("TAKEOWNERSHIP", HELP_TAKEOWNERSHIP),
- "PROTOCOLINFO": ("PROTOCOLINFO [ProtocolVersion]", HELP_PROTOCOLINFO),
-}
-
-class ControlInterpreter:
- """
- Interpretor that handles queries to the control port, providing usability
- imporvements like irc style help optoins. This tracks input and responses.
- """
-
- def do_help(self, arg, output_entry):
- """
- Performs the '/help' operation, giving usage information for the given
- argument or a general summary if there wasn't one.
- """
-
- arg = arg.upper()
-
- # If there's multiple arguments then just take the first. This is
- # particularly likely if they're trying to query a full command (for
- # instance "/help GETINFO version")
- arg = arg.split(" ")[0]
-
- # strip slash if someone enters an interpretor command (ex. "/help /help")
- if arg.startswith("/"): arg = arg[1:]
-
- if arg:
- if arg in HELP_OPTIONS:
- # Provides information for the tor or interpretor argument. This bolds
- # the usage information and indents the description after it.
- usage, description = HELP_OPTIONS[arg]
-
- output_entry.append([(usage, BLUE, BOLD)])
-
- for line in description.split("\n"):
- output_entry.append([(" " + line, BLUE, )])
-
- if arg == "SIGNAL":
- # lists descriptions for all of the signals
- for signal, description in SIGNAL_DESCRIPTIONS:
- output_entry.append([("%-15s" % signal, BLUE, BOLD), (" - %s" % description, BLUE, )])
- elif arg == "SETEVENTS":
- # lists all of the event types
- event_options = tor_controller().get_info("events/names")
- if event_options:
- event_entries = event_options.split()
-
- # displays four columns of 20 characters
- for i in range(0, len(event_entries), 4):
- line_entries = event_entries[i : i+4]
-
- line_content = ""
- for entry in line_entries:
- line_content += "%-20s" % entry
-
- output_entry.append([(line_content, BLUE, )])
- elif arg == "USEFEATURE":
- # lists the feature options
- feature_options = tor_controller().get_info("features/names")
- if feature_options:
- output_entry.append([(feature_options, BLUE, )])
- elif arg in ("LOADCONF", "POSTDESCRIPTOR"):
- # gives a warning that this option isn't yet implemented
- output_entry.append([(MULTILINE_UNIMPLEMENTED_NOTICE, RED, BOLD)])
- else:
- output_entry.append([("No help information available for '%s'..." % arg, RED, BOLD)])
- else:
- # provides the GENERAL_HELP with everything bolded except descriptions
- for line in GENERAL_HELP.split("\n"):
- cmd_start = line.find(" - ")
- if cmd_start != -1:
- output_entry.append([(line[:cmd_start], BLUE, BOLD), (line[cmd_start:], BLUE, )])
- else:
- output_entry.append([(line, BLUE, BOLD)])
-
- def handle_query(self, user_input):
- """
- Processes the given input. Requests starting with a '/' are special
- commands to the interpretor, and anything else is sent to the control port.
- This returns an input/output tuple, each entry being a list of lines, each
- line having a list of (msg, format) tuples for the content to be displayed.
- This raises a InterpretorClosed if the interpretor should be shut down.
-
- Arguments:
- user_input - user input to be processed
- """
-
- user_input = user_input.strip()
-
- input_entry, output_entry = [], []
-
- if " " in user_input: cmd, arg = user_input.split(" ", 1)
- else: cmd, arg = user_input, ""
-
- if cmd.startswith("/"):
- input_entry.append((user_input, MAGENTA, BOLD))
- if cmd == "/quit": raise InterpreterClosed()
- elif cmd == "/help": self.do_help(arg, output_entry)
- else:
- output_entry.append([("Not yet implemented...", RED, BOLD)])
- else:
- cmd = cmd.upper()
- input_entry.append((cmd + " ", GREEN, BOLD))
- if arg:
- input_entry.append((arg, CYAN, BOLD))
-
- if cmd == "GETINFO":
- resp = tor_controller().get_info(arg)
- for line in resp.split('\n'):
- output_entry.append([(line, CYAN,)])
-
- return input_entry, output_entry
-
-
-class InterpreterClosed(Exception):
- """
- Exception raised when the interpreter should be shut down.
- """
-
- pass
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits