[tor-commits] [stem/master] Whitelist support for shell commands

atagar at torproject.org atagar at torproject.org
Thu Jan 3 17:59:46 UTC 2013


commit ec1078ccc39af8d154ef2f70781f1a3787be6789
Author: Damian Johnson <atagar at torproject.org>
Date:   Thu Jan 3 09:42:39 2013 -0800

    Whitelist support for shell commands
    
    Shell commands have at times been the bane of my existance. They live outside
    the PATH (causing our is_available() to fail), and now it turns out that
    subprocess.Popen() fails to find them too. In retrospect both make sense but at
    first both are worthy of some head scratching.
    
    Adding a whitelist we can add shell commands to so they'll behave as we expect.
---
 stem/util/system.py |   30 ++++++++++++++++++++++--------
 1 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/stem/util/system.py b/stem/util/system.py
index 0b4427e..080b080 100644
--- a/stem/util/system.py
+++ b/stem/util/system.py
@@ -31,11 +31,18 @@ import stem.util.proc
 from stem import UNDEFINED, CircStatus
 from stem.util import log
 
-# Mapping of commands to if they're available or not. This isn't always
-# reliable, failing for some special commands. For these the cache is
-# prepopulated to skip lookups.
+# Mapping of commands to if they're available or not.
 
-CMD_AVAILABLE_CACHE = {"ulimit": True}
+CMD_AVAILABLE_CACHE = {}
+
+# An incomplete listing of commands provided by the shell. Expand this as
+# needed. Some noteworthy things about shell commands...
+#
+# * They're not in the path so is_available() will fail.
+# * subprocess.Popen() without the 'shell = True' argument will fail with...
+#   OSError: [Errno 2] No such file or directory
+
+SHELL_COMMANDS = ['ulimit']
 
 IS_RUNNING_PS_LINUX      = "ps -A co command"
 IS_RUNNING_PS_BSD        = "ps -ao ucomm="
@@ -86,8 +93,9 @@ def is_available(command, cached=True):
   than one command is present (for instance "ls -a | grep foo") then this
   just checks the first.
   
-  Note that many builtin common commands (like cd and ulimit) aren't in the
-  PATH so this lookup will fail for them.
+  Note that shell (like cd and ulimit) aren't in the PATH so this lookup will
+  try to assume that it's available. This only happends for recognized shell
+  commands (those in SHELL_COMMANDS).
   
   :param str command: command to search for
   :param bool cached: makes use of available cached results if **True**
@@ -98,7 +106,11 @@ def is_available(command, cached=True):
   
   if " " in command: command = command.split(" ")[0]
   
-  if cached and command in CMD_AVAILABLE_CACHE:
+  if command in SHELL_COMMANDS:
+    # we can't actually look it up, so hope the shell really provides it...
+    
+    return True
+  elif cached and command in CMD_AVAILABLE_CACHE:
     return CMD_AVAILABLE_CACHE[command]
   else:
     cmd_exists = False
@@ -568,8 +580,10 @@ def call(command, default = UNDEFINED):
   """
   
   try:
+    is_shell_command = command.split(" ")[0] in SHELL_COMMANDS
+    
     start_time = time.time()
-    stdout, stderr = subprocess.Popen(command.split(), stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
+    stdout, stderr = subprocess.Popen(command.split(), stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = is_shell_command).communicate()
     stdout, stderr = stdout.strip(), stderr.strip()
     runtime = time.time() - start_time
     



More information about the tor-commits mailing list