[tor-commits] [stem/master] Add doc and fix whitespace

atagar at torproject.org atagar at torproject.org
Thu Jul 19 16:01:03 UTC 2012


commit 4d88884b0cfdc98ca4c4741d4e1073267418038c
Author: Sathyanarayanan Gunasekaran <gsathya.ceg at gmail.com>
Date:   Fri Mar 23 15:18:44 2012 +0530

    Add doc and fix whitespace
---
 stem/exit_policy.py |  303 +++++++++++++++++++++++++++++----------------------
 1 files changed, 171 insertions(+), 132 deletions(-)

diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 287b620..0a51f5f 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -1,152 +1,191 @@
+"""
+Tor Exit Policy information and requirements for its features. These can be
+easily parsed and compared, for instance...
+
+>>> exit_policies = stem.exit_policy.ExitPolicy()
+>>> exit_policies.add("reject *:*")
+>>> print exit_policies
+reject *:*
+
+ExitPolicyLine - Single rule from the exit policy
+  |- __str__ - string representation
+  +- check   - check if exiting to this ip is allowed
+
+ExitPolicy - List of ExitPolicyLine objects
+  |- __str__  - string representation
+  |- __iter__ - ExitPolicyLine entries for the exit policy
+  |- check    - check if exiting to this ip is allowed
+  |- add      - add new rule to the exit policy
+  +- isExitingAllowed - check if exit node
+"""
+
 # ip address ranges substituted by the 'private' keyword
 PRIVATE_IP_RANGES = ("0.0.0.0/8", "169.254.0.0/16", "127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12")
 
 class ExitPolicyLine:
-    def __init__(self, ruleEntry):
-        # sanitize the input a bit, cleaning up tabs and stripping quotes
-        ruleEntry = ruleEntry.replace("\\t", " ").replace("\"", "")
-
-        self.ruleEntry = ruleEntry
-        self.isAccept = ruleEntry.startswith("accept")
-
-        # strips off "accept " or "reject " and extra spaces
-        ruleEntry = ruleEntry[7:].replace(" ", "")
-
-        # split ip address (with mask if provided) and port
-        if ":" in ruleEntry: entryIp, entryPort = ruleEntry.split(":", 1)
-        else: entryIp, entryPort = ruleEntry, "*"
-
-        # sets the ip address component
-        self.isIpWildcard = entryIp == "*" or entryIp.endswith("/0")
-
-        if "/" in entryIp:
-            ipComp = entryIp.split("/", 1)
-            self.ipAddress = ipComp[0]
-            self.ipMask = int(ipComp[1])
-        else:
-            self.ipAddress = entryIp
-            self.ipMask = 32
-
-        # constructs the binary address just in case of comparison with a mask
-        if self.ipAddress != "*":
-            self.ipAddressBin = ""
-            for octet in self.ipAddress.split("."):
-                # Converts the int to a binary string, padded with zeros. Source:
-                # http://www.daniweb.com/code/snippet216539.html
-                self.ipAddressBin += "".join([str((int(octet) >> y) & 1) for y in range(7, -1, -1)])
-        else:
-            self.ipAddressBin = "0" * 32
+  """
+  Single rule from the user's exit policy. These are chained together to form
+  complete policies.
+  """
 
-        # sets the port component
-        self.minPort, self.maxPort = 0, 0
-        self.isPortWildcard = entryPort == "*"
-
-        if entryPort != "*":
-            if "-" in entryPort:
-                portComp = entryPort.split("-", 1)
-                self.minPort = int(portComp[0])
-                self.maxPort = int(portComp[1])
-            else:
-                self.minPort = int(entryPort)
-                self.maxPort = int(entryPort)
-        
-    def __str__(self):
-        # This provides the actual policy rather than the entry used to construct
-        # it so the 'private' keyword is expanded.
-        
-        acceptanceLabel = "accept" if self.isAccept else "reject"
+  def __init__(self, rule_entry):
+    """
+    Exit Policy line constructor.
+    """
+    # sanitize the input a bit, cleaning up tabs and stripping quotes
+    rule_entry = rule_entry.replace("\\t", " ").replace("\"", "")
     
-        if self.isIpWildcard:
-            ipLabel = "*"
-        elif self.ipMask != 32:
-            ipLabel = "%s/%i" % (self.ipAddress, self.ipMask)
-        else: ipLabel = self.ipAddress
+    self.rule_entry = rule_entry
+    self.is_accept = rule_entry.startswith("accept")
     
-        if self.isPortWildcard:
-            portLabel = "*"
-        elif self.minPort != self.maxPort:
-            portLabel = "%i-%i" % (self.minPort, self.maxPort)
-        else: portLabel = str(self.minPort)
+    # strips off "accept " or "reject " and extra spaces
+    rule_entry = rule_entry[7:].replace(" ", "")
     
-        myPolicy = "%s %s:%s" % (acceptanceLabel, ipLabel, portLabel)
-        return myPolicy
+    # split ip address (with mask if provided) and port
+    if ":" in rule_entry: entry_ip, entry_port = rule_entry.split(":", 1)
+    else: entry_ip, entry_port = rule_entry, "*"
     
-    def check(self, ipAddress, port):
-        """
-        Checks if the rule chain allows exiting to this address, returning true if
-        so and false otherwise.
-        """
+    # sets the ip address component
+    self.is_ip_wildcard = entry_ip == "*" or entry_ip.endswith("/0")
     
-        port = int(port)
+    # separate host and mask
+    if "/" in entry_ip:
+      ip_comp = entry_ip.split("/", 1)
+      self.ip_address = ip_comp[0]
+      self.ip_mask = int(ip_comp[1])
+    else:
+      self.ip_address = entry_ip
+      self.ip_mask = 32
     
-        # does the port check first since comparing ip masks is more work
-        isPortMatch = self.isPortWildcard or (port >= self.minPort and port <= self.maxPort)
+    # constructs the binary address just in case of comparison with a mask
+    if self.ip_address != "*":
+      self.ip_address_bin = ""
+      for octet in self.ip_address.split("."):
+        # Converts the int to a binary string, padded with zeros. Source:
+        # http://www.daniweb.com/code/snippet216539.html
+        self.ip_address_bin += "".join([str((int(octet) >> y) & 1) for y in range(7, -1, -1)])
+    else:
+      self.ip_address_bin = "0" * 32
+      
+    # sets the port component
+    self.min_port, self.max_port = 0, 0
+    self.is_port_wildcard = entry_port == "*"
     
-        if isPortMatch:
-            isIpMatch = self.isIpWildcard or self.ipAddress == ipAddress
+    if entry_port != "*":
+      if "-" in entry_port:
+        port_comp = entry_port.split("-", 1)
+        self.min_port = int(port_comp[0])
+        self.max_port = int(port_comp[1])
+      else:
+        self.min_port = int(entry_port)
+        self.max_port = int(entry_port)
         
-            # expands the check to include the mask if it has one
-            if not isIpMatch and self.ipMask != 32:
-                inputAddressBin = ""
-                for octet in ipAddress.split("."):
-                    inputAddressBin += "".join([str((int(octet) >> y) & 1) for y in range(7, -1, -1)])
-
-                isIpMatch = self.ipAddressBin[:self.ipMask] == inputAddressBin[:self.ipMask]
-
-            if isIpMatch: return self.isAccept
+  def __str__(self):
+    # This provides the actual policy rather than the entry used to construct
+    # it so the 'private' keyword is expanded.
+        
+    acceptance_label = "accept" if self.is_accept else "reject"
+        
+    if self.is_ip_wildcard:
+      ip_label = "*"
+    elif self.ip_mask != 32:
+      ip_label = "%s/%i" % (self.ip_address, self.ip_mask)
+    else: ip_label = self.ip_address
+        
+    if self.is_port_wildcard:
+      port_label = "*"
+    elif self.min_port != self.max_port:
+      port_label = "%i-%i" % (self.min_port, self.max_port)
+    else: port_label = str(self.min_port)
+        
+    my_policy = "%s %s:%s" % (acceptance_label, ip_label, port_label)
+    return my_policy
+    
+  def check(self, ip_address, port):
+    """
+    Checks if the rule chain allows exiting to this address, returning true if
+    so and false otherwise.
+    """
+      
+    port = int(port)
+    
+    # does the port check first since comparing ip masks is more work
+    is_port_match = self.is_port_wildcard or (port >= self.min_port and port <= self.max_port)
+    
+    if is_port_match:
+      is_ip_match = self.is_ip_wildcard or self.ip_address == ip_address
+        
+       # expands the check to include the mask if it has one
+      if not is_ip_match and self.ip_mask != 32:
+        input_address_bin = ""
+        for octet in ip_address.split("."):
+          input_address_bin += "".join([str((int(octet) >> y) & 1) for y in range(7, -1, -1)])
+
+        is_ip_match = self.ip_address_bin[:self.ip_mask] == input_address_bin[:self.ip_mask]
+                
+      if is_ip_match: return self.is_accept
             
-        # fell off the chain without a conclusion (shouldn't happen...)
-        return False
+    # fell off the chain without a conclusion (shouldn't happen...)
+    return False
       
-
+    
 class ExitPolicy:
+  """
+  Provides a wrapper to ExitPolicyLine. This is iterable and can be stringified for
+  individual Exit Policy lines.
+  """
+    
+  def __init__(self):
     """
-    Single rule from the user's exit policy. These are chained together to form
-    complete policies.
+    ExitPolicy constructor
     """
-  
-    def __init__(self):
-        """
-        Exit policy rule constructor.
-        """
-        self._policies = []
-  
-    def add(self, ruleEntry):
-        # checks for the private alias (which expands this to a chain of entries)
-        if "private" in ruleEntry.lower():
-            for addr in PRIVATE_IP_RANGES:
-                newEntry = ruleEntry.replace("private", addr)
-                self._policies.append(ExitPolicyLine(newEntry))
-        else:
-            self._policies.append(ExitPolicyLine(ruleEntry))
-
-    def isExitingAllowed(self):
-        """
-        Provides true if the policy allows exiting whatsoever, false otherwise.
-        """
-        for policy in self._policies:
-          if policy.isAccept: return True
-          elif policy.isIpWildcard and self.isPortWildcard: return False
-
-  
-    def check(self, ipAddress, port):
-        """
-        Checks if the rule chain allows exiting to this address, returning true if
-        so and false otherwise.
-        """
-    
-        for policy in self._policies:
-            if policy.check(ipAddress, port): return True
+    self._policies = []
 
-        return False
-  
-    def __iter__(self):
-        for policy in self._policies:
-            yield policy
+  def add(self, rule_entry):
+    """
+    This method is used to add an Exit Policy rule to the list of policies.
+        
+    Arguments:
+    rule_entry (str) - exit policy rule in the format "accept|reject ADDR[/MASK][:PORT]"
+                       ex - "accept 18.7.22.69:*"
+    """
+        # checks for the private alias (which expands this to a chain of entries)
+    if "private" in rule_entry.lower():
+      for addr in PRIVATE_IP_RANGES:
+        new_entry = rule_entry.replace("private", addr)
+        self._policies.append(ExitPolicyLine(new_entry))
+    else:
+      self._policies.append(ExitPolicyLine(rule_entry))
+    
+  def is_exiting_allowed(self):
+    """
+    Provides true if the policy allows exiting whatsoever, false otherwise.
+    """
+    for policy in self._policies:
+      if policy.is_accept: return True
+      elif policy.is_ip_wildcard and policy.is_port_wildcard: return False
+    
+  def check(self, ip_address, port):
+    """
+    Checks if the rule chain allows exiting to this address, returning true if
+    so and false otherwise.
+    """
+    
+    for policy in self._policies:
+      if policy.check(ip_address, port): return True
+        
+      return False
+    
+  def __iter__(self):
+    """
+    Provides an ordered listing of policies in this Exit Policy
+    """
+    for policy in self._policies:
+      yield policy
+    
+  def __str__(self):
+    """
+    Provides the string used to construct the Exit Policy      
+    """
+    return ' , '.join([str(policy) for policy in self._policies])
   
-    def __str__(self):
-        # This provides the actual policy rather than the entry used to construct
-        # it so the 'private' keyword is expanded.
-      
-        return ' , '.join([str(policy) for policy in self._policies])
-





More information about the tor-commits mailing list