[tor-commits] [nyx/master] Drop all torrc validations

atagar at torproject.org atagar at torproject.org
Sun Feb 14 02:55:49 UTC 2016


commit 302d4d56676503bda6d4d3bfb92b2f8e425bedfa
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Feb 6 13:58:13 2016 -0800

    Drop all torrc validations
    
    Ok, screw it. Hours now I've been staring at this code to figure out if it
    should be salvaged or not. Final conclusion: no.
    
      1. This is a feature nobody wants. I've spent a silly amount of time making
         it work while honestly our users would be happier if Nyx simply didn't.
    
      2. Tor makes this hard to do reliably. There's torrc aliases, multi-line
         entries, unit conversions, etc. Way too much headache for its negligible
         value.
---
 nyx/settings/torrc.cfg |  53 -----------
 nyx/torrc_panel.py     |  23 +----
 nyx/util/tor_config.py | 245 -------------------------------------------------
 3 files changed, 1 insertion(+), 320 deletions(-)

diff --git a/nyx/settings/torrc.cfg b/nyx/settings/torrc.cfg
deleted file mode 100644
index 71d4608..0000000
--- a/nyx/settings/torrc.cfg
+++ /dev/null
@@ -1,53 +0,0 @@
-################################################################################
-#
-# Information related to tor configuration options. This has two sections...
-#
-#   * torrc.alias       Aliases for configuration options tor will accept.
-#   * torrc.units       Labels accepted by tor for various units.
-#
-################################################################################
-
-# Torrc aliases from the _option_abbrevs struct of 'src/or/config.c'. These
-# couldn't be requested via GETCONF as of 0.2.1.19, but this might have been
-# fixed. Discussion is in...
-#
-#   https://trac.torproject.org/projects/tor/ticket/1802
-#
-# TODO: Check if this workaround can be dropped later.
-
-torrc.alias l => Log
-torrc.alias AllowUnverifiedNodes => AllowInvalidNodes
-torrc.alias AutomapHostSuffixes => AutomapHostsSuffixes
-torrc.alias AutomapHostOnResolve => AutomapHostsOnResolve
-torrc.alias BandwidthRateBytes => BandwidthRate
-torrc.alias BandwidthBurstBytes => BandwidthBurst
-torrc.alias DirFetchPostPeriod => StatusFetchPeriod
-torrc.alias MaxConn => ConnLimit
-torrc.alias ORBindAddress => ORListenAddress
-torrc.alias DirBindAddress => DirListenAddress
-torrc.alias SocksBindAddress => SocksListenAddress
-torrc.alias UseHelperNodes => UseEntryGuards
-torrc.alias NumHelperNodes => NumEntryGuards
-torrc.alias UseEntryNodes => UseEntryGuards
-torrc.alias NumEntryNodes => NumEntryGuards
-torrc.alias ResolvConf => ServerDNSResolvConfFile
-torrc.alias SearchDomains => ServerDNSSearchDomains
-torrc.alias ServerDNSAllowBrokenResolvConf => ServerDNSAllowBrokenConfig
-torrc.alias PreferTunnelledDirConns => PreferTunneledDirConns
-torrc.alias BridgeAuthoritativeDirectory => BridgeAuthoritativeDir
-torrc.alias StrictEntryNodes => StrictNodes
-torrc.alias StrictExitNodes => StrictNodes
-
-# Size and time modifiers allowed by 'src/or/config.c'.
-
-torrc.units.size.b b, byte, bytes
-torrc.units.size.kb kb, kbyte, kbytes, kilobyte, kilobytes
-torrc.units.size.mb m, mb, mbyte, mbytes, megabyte, megabytes
-torrc.units.size.gb gb, gbyte, gbytes, gigabyte, gigabytes
-torrc.units.size.tb tb, terabyte, terabytes
-
-torrc.units.time.sec second, seconds
-torrc.units.time.min minute, minutes
-torrc.units.time.hour hour, hours
-torrc.units.time.day day, days
-torrc.units.time.week week, weeks
diff --git a/nyx/torrc_panel.py b/nyx/torrc_panel.py
index e37c9b5..0b456d8 100644
--- a/nyx/torrc_panel.py
+++ b/nyx/torrc_panel.py
@@ -5,7 +5,7 @@ Panel displaying the torrc or nyxrc with the validation done against it.
 import math
 import curses
 
-from nyx.util import expand_path, panel, tor_config, tor_controller, ui_tools
+from nyx.util import expand_path, panel, tor_controller, ui_tools
 
 from stem.control import State
 from stem.util import log, str_tools
@@ -131,7 +131,6 @@ class TorrcPanel(panel.Panel):
 
     if self.torrc_content is None:
       rendered_contents = ['### Unable to load the torrc ###']
-      corrections = {}
     else:
       rendered_contents = [ui_tools.get_printable(line.replace('\t', '   ')) for line in self.torrc_content]
 
@@ -142,8 +141,6 @@ class TorrcPanel(panel.Panel):
           if line and '#' in line:
             rendered_contents[i] = line[:line.find('#')].strip()
 
-      corrections = tor_config.validate(self.torrc_content)
-
     # offset to make room for the line numbers
 
     line_number_offset = 0
@@ -222,24 +219,6 @@ class TorrcPanel(panel.Panel):
       if stripped_line:
         is_multiline = stripped_line.endswith('\\')
 
-      # gets the correction
-
-      if line_number in corrections:
-        line_issue, line_issue_msg = corrections[line_number]
-
-        if line_issue in (tor_config.ValidationError.DUPLICATE, tor_config.ValidationError.IS_DEFAULT):
-          line_comp['option'][1] = (curses.A_BOLD, 'blue')
-          line_comp['argument'][1] = (curses.A_BOLD, 'blue')
-        elif line_issue == tor_config.ValidationError.MISMATCH:
-          line_comp['argument'][1] = (curses.A_BOLD, 'red')
-          line_comp['correction'][0] = ' (%s)' % line_issue_msg
-        else:
-          # For some types of configs the correction field is simply used to
-          # provide extra data (for instance, the type for tor state fields).
-
-          line_comp['correction'][0] = ' (%s)' % line_issue_msg
-          line_comp['correction'][1] = (curses.A_BOLD, 'magenta')
-
       # draws the line number
 
       if self.show_line_num and display_line < height and display_line >= 1:
diff --git a/nyx/util/tor_config.py b/nyx/util/tor_config.py
deleted file mode 100644
index e8b82b3..0000000
--- a/nyx/util/tor_config.py
+++ /dev/null
@@ -1,245 +0,0 @@
-"""
-Helper functions for working with tor's configuration file.
-"""
-
-from nyx.util import tor_controller
-
-from stem.util import conf, enum, str_tools
-
-CONFIG = conf.config_dict('nyx', {
-  'torrc.alias': {},
-  'torrc.units.size.b': [],
-  'torrc.units.size.kb': [],
-  'torrc.units.size.mb': [],
-  'torrc.units.size.gb': [],
-  'torrc.units.size.tb': [],
-  'torrc.units.time.sec': [],
-  'torrc.units.time.min': [],
-  'torrc.units.time.hour': [],
-  'torrc.units.time.day': [],
-  'torrc.units.time.week': [],
-  'tor.chroot': '',
-})
-
-
-def general_conf_handler(config, key):
-  value = config.get(key)
-
-  if key.startswith('torrc.units.') and value:
-    # all the torrc.units.* values are comma separated lists
-    return [entry.strip() for entry in value[0].split(',')]
-
-
-conf.get_config('nyx').add_listener(general_conf_handler, backfill = True)
-
-# enums and values for numeric torrc entries
-
-ValueType = enum.Enum('UNRECOGNIZED', 'SIZE', 'TIME')
-SIZE_MULT = {'b': 1, 'kb': 1024, 'mb': 1048576, 'gb': 1073741824, 'tb': 1099511627776}
-TIME_MULT = {'sec': 1, 'min': 60, 'hour': 3600, 'day': 86400, 'week': 604800}
-
-# enums for issues found during torrc validation:
-# DUPLICATE  - entry is ignored due to being a duplicate
-# MISMATCH   - the value doesn't match tor's current state
-# IS_DEFAULT - the configuration option matches tor's default
-
-ValidationError = enum.Enum('DUPLICATE', 'MISMATCH', 'IS_DEFAULT')
-
-MULTILINE_PARAM = None  # cached multiline parameters (lazily loaded)
-
-
-def get_multiline_parameters():
-  """
-  Provides parameters that can be defined multiple times in the torrc without
-  overwriting the value.
-  """
-
-  # fetches config options with the LINELIST (aka 'LineList'), LINELIST_S (aka
-  # 'Dependent'), and LINELIST_V (aka 'Virtual') types
-
-  global MULTILINE_PARAM
-
-  if MULTILINE_PARAM is None:
-    controller, multiline_entries = tor_controller(), []
-
-    config_option_query = controller.get_info('config/names', None)
-
-    if config_option_query:
-      for line in config_option_query.strip().split('\n'):
-        conf_option, conf_type = line.strip().split(' ', 1)
-
-        if conf_type in ('LineList', 'Dependant', 'Virtual'):
-          multiline_entries.append(conf_option)
-    else:
-      # unable to query tor connection, so not caching results
-      return ()
-
-    MULTILINE_PARAM = multiline_entries
-
-  return tuple(MULTILINE_PARAM)
-
-
-def validate(contents):
-  """
-  Performs validation on the given torrc contents, providing back a listing of
-  (line number, issue, msg) tuples for issues found. If the issue occures on a
-  multiline torrc entry then the line number is for the last line of the entry.
-
-  Arguments:
-    contents - torrc contents
-  """
-
-  controller = tor_controller()
-
-  config_text = controller.get_info('config-text', None)
-  config_lines = config_text.splitlines() if config_text else []
-  custom_options = list(set([line.split(' ')[0] for line in config_lines]))
-
-  issues_found, seen_options = {}, []
-
-  # Strips comments and collapses multiline multi-line entries, for more
-  # information see:
-  # https://trac.torproject.org/projects/tor/ticket/1929
-
-  stripped_contents, multiline_buffer = [], ''
-
-  for line in contents:
-    if '#' in line:
-      line = line[:line.find('#')]
-
-    line = line.strip()
-
-    if not line:
-      stripped_contents.append('')
-    else:
-      line = multiline_buffer + line
-      multiline_buffer = ''
-
-      if line.endswith('\\'):
-        multiline_buffer = line[:-1]
-        stripped_contents.append('')
-      else:
-        stripped_contents.append(line.strip())
-
-  for line_number in range(len(stripped_contents) - 1, -1, -1):
-    line_text = stripped_contents[line_number]
-
-    if not line_text:
-      continue
-
-    line_comp = line_text.split(None, 1)
-
-    if len(line_comp) == 2:
-      option, value = line_comp
-    else:
-      option, value = line_text, ''
-
-    # Tor is case insensetive when parsing its torrc. This poses a bit of an
-    # issue for us because we want all of our checks to be case insensetive
-    # too but also want messages to match the normal camel-case conventions.
-    #
-    # Using the custom_options to account for this. It contains the tor reported
-    # options (camel case) and is either a matching set or the following defaut
-    # value check will fail. Hence using that hash to correct the case.
-    #
-    # TODO: when refactoring for stem make this less confusing...
-
-    for custom_opt in custom_options:
-      if custom_opt.lower() == option.lower():
-        option = custom_opt
-        break
-
-    # if an aliased option then use its real name
-
-    if option in CONFIG['torrc.alias']:
-      option = CONFIG['torrc.alias'][option]
-
-    # most parameters are overwritten if defined multiple times
-
-    if option in seen_options and option not in get_multiline_parameters():
-      issues_found[line_number] = (ValidationError.DUPLICATE, option)
-      continue
-    else:
-      seen_options.append(option)
-
-    # checks if the value isn't necessary due to matching the defaults
-
-    if option not in custom_options:
-      issues_found[line_number] = (ValidationError.IS_DEFAULT, option)
-
-    # replace aliases with their recognized representation
-
-    if option in CONFIG['torrc.alias']:
-      option = CONFIG['torrc.alias'][option]
-
-    # tor appears to replace tabs with a space, for instance:
-    # "accept\t*:563" is read back as "accept *:563"
-
-    value = value.replace('\t', ' ')
-
-    # parse value if it's a size or time, expanding the units
-
-    value, value_type = _parse_conf_value(value)
-
-    # issues GETCONF to get the values tor's currently configured to use
-
-    tor_values = controller.get_conf(option, [], True)
-
-    # multiline entries can be comma separated values (for both tor and conf)
-
-    value_list = [value]
-
-    if option in get_multiline_parameters():
-      value_list = [val.strip() for val in value.split(',')]
-
-      fetched_values, tor_values = tor_values, []
-      for fetched_value in fetched_values:
-        for fetched_entry in fetched_value.split(','):
-          fetched_entry = fetched_entry.strip()
-
-          if fetched_entry not in tor_values:
-            tor_values.append(fetched_entry)
-
-    for val in value_list:
-      # checks if both the argument and tor's value are empty
-
-      is_blank_match = not val and not tor_values
-
-      if not is_blank_match and val not in tor_values:
-        # converts corrections to reader friedly size values
-
-        display_values = tor_values
-
-        if value_type == ValueType.SIZE:
-          display_values = [str_tools.size_label(int(val)) for val in tor_values]
-        elif value_type == ValueType.TIME:
-          display_values = [str_tools.time_label(int(val)) for val in tor_values]
-
-        issues_found[line_number] = (ValidationError.MISMATCH, ', '.join(display_values))
-
-  return issues_found
-
-
-def _parse_conf_value(conf_arg):
-  """
-  Converts size or time values to their lowest units (bytes or seconds) which
-  is what GETCONF calls provide. The returned is a tuple of the value and unit
-  type.
-
-  Arguments:
-    conf_arg - torrc argument
-  """
-
-  if conf_arg.count(' ') == 1:
-    val, unit = conf_arg.lower().split(' ', 1)
-
-    if val.isdigit():
-      for label in SIZE_MULT:
-        if unit in CONFIG['torrc.units.size.' + label]:
-          return str(int(val) * SIZE_MULT[label]), ValueType.SIZE
-
-      for label in TIME_MULT:
-        if unit in CONFIG['torrc.units.time.' + label]:
-          return str(int(val) * TIME_MULT[label]), ValueType.TIME
-
-  return conf_arg, ValueType.UNRECOGNIZED





More information about the tor-commits mailing list