1. Georg Brandl
  2. rac

Commits

g...@Georglap  committed d5cb7f9

Add some more policies.

  • Participants
  • Parent commits adba93e
  • Branches default

Comments (0)

Files changed (6)

File rac.conf.py

View file
 # * username - name of the file's owner
 vhostprefix = """
 ServerName %(basename)s
-SuexecUserGroup %(username)s %(username)s
+SuexecUserGroup %(username)s users
 """
 
 # The custom policy for contexts (<Foo> sections).  This extends the
 directive_policy = {
 
 }
+
+# Allowed base paths for the default check_path policy.  Only path names
+# which are under one of these paths in a directory named after the user
+# are accepted.
+# Example: if this is ['/home'] and the user is 'hans', only paths under
+#          /home/hans are accepted.
+acceptable_paths = [
+    '/home',
+    '/var/www'
+]

File rac/check.py

View file
 """
 
 from rac.parser import Parser, ParsingError, ContextNode
-from rac.policy import contexts, directives
 
 
 class ValidationError(Exception):
         raise ValidationError(str(err))
     f.close()
 
+    from rac.policy import contexts, directives
     ctxs = contexts.copy()
     ctxs.update(config.get('context_policy', {}))
     dirs = directives.copy()
     # for now, a simple tree traversal
     for node in nodetree.traverse():
         if isinstance(node, ContextNode):
-            entry = ctxs.get(node.name, defctx)
+            entry = ctxs.get(node.name.lower(), defctx)
         else:
-            entry = dirs.get(node.name, defdir)
+            entry = dirs.get(node.name.lower(), defdir)
         if callable(entry):
-            entry = entry(config, user, node)
+            try:
+                entry = entry(config, user, node)
+            except ValidationError, err:
+                # pass these through, but add context info
+                err.args = (err.args[0] + ' (%s %r, line %d)' %
+                            (node.type, node.name, node.lno),) + err.args[1:]
+                raise
+            except:
+                raise
+                raise ValidationError('validator raised for %s %r on line %d' %
+                                      (node.type, node.name, node.lno))
         if not entry:
             raise ValidationError('the %s %r on line %d is not allowed' %
                                   (node.type, node.name, node.lno))

File rac/dhandler.py

View file
             os.write(fileno, f.read()+'\n')
             f.close()
 
-    os.write(fileno, '<VirtualHost *:80>\n')
+    os.write(fileno, '<VirtualHost *>\n')
     os.write(fileno, config.get('vhostprefix', '') %
              {'basename': os.path.basename(filename), 'username': user})
     sf = file(filename, 'r')
             log.debug('installing %r to %s', fn, targetdir)
             sf = open(fn, 'r')
             tf = open(os.path.join(targetdir, b), 'w')
-            tf.write('<VirtualHost *:80>\n')
+            tf.write('<VirtualHost *>\n')
             tf.write(config.get('vhostprefix', '') % {'basename': b, 'username': user})
             tf.write(sf.read())
             tf.write('\n</VirtualHost>\n')

File rac/parser.py

View file
             # handle context end
             m = _ce_re.match(line)
             if m:
-                ctxname = m.group(1).lower()
+                ctxname = m.group(1)
                 if ctxname == 'root':
                     raise ParsingError("unknown context '_root'", lno)
-                if ctxstack[-1].name != ctxname:
+                if ctxstack[-1].name.lower() != ctxname.lower():
                     raise ParsingError('context %r closed but context %r was open' %
-                                       (ctxname, ctxstack[-1]), lno)
+                                       (ctxname, ctxstack[-1].name), lno)
                 del ctxstack[-1]
                 continue
             # handle context begin
             m = _cb_re.match(line)
             if m:
-                ctxname = m.group(1).lower()
+                ctxname = m.group(1)
                 node = ContextNode(ctxstack[-1], ctxname, m.group(2), lno)
                 ctxstack[-1].children.append(node)
                 ctxstack.append(node)
             m = _di_re.match(line)
             if not m:
                 raise ParsingError('expected directive', lno)
-            dirname = m.group(1).lower()
+            dirname = m.group(1)
             ctxstack[-1].children.append(
                 DirectiveNode(ctxstack[-1], dirname, m.group(2), lno))
         if len(ctxstack) > 1:

File rac/policy.py

View file
 contexts = {
     'virtualhost': False,
 
-    'directory': directory,
-    'directorymatch': False,
+    'directory': True,
+    'directorymatch': True,
     'location': True,
     'locationmatch': True,
     'files': True,
     # all unknown contexts
     '__default__': False,
 
-    # the virtual root node
+    # the virtual root node - must be true
     '_root': True,
 }
 
 
 directives = {
-    'include': False,
-    'loadmodule': False,
-    'suexecusergroup': False,
+    'serveralias': 1,
+    'documentroot': check_path(0),
+    'scriptalias': check_path(1),
+    'options': check_options,
+    'alias': check_path(1),
+    'sethandler': 1,
+    'redirect': 1,
+    'setenv': 1,
+
+    # logging
+    'transferlog': check_path(0),
+    'errorlog': check_path(0),
+    'customlog': check_path(0),
+    'logformat': 1,
+    'loglevel': 1,
+
+    # authn
+    'authtype': 1,
+    'authname': 1,
+    'authuserfile': 1,
+    'require': 1,
+
+    # svn
+    'dav': 1,
+    'svnpath': 1,
+    'svnindexxslt': 1,
+
+    # rewrite
+    'rewriteengine': 1,
+    'rewriterule': 1,
+    'rewritecond': 1,
+    'rewritebase': 1,
 
     # all unknown directives
-    '__default__': True,
+    '__default__': False,
 }

File rac/validators.py

View file
     :license: BSD license.
 """
 
-# Reject Directory directives with wildcards
+import shlex
+from os import path
 
-def directory(config, user, node):
+from rac.check import ValidationError
+
+
+def check_path(which):
+    def check(config, user, node):
+        args = shlex.split(node.args)
+        try:
+            myarg = args[which]
+        except:
+            raise ValidationError('not enough args')
+        acceptable = config.get('acceptable_paths', ['/home', '/var/www'])
+        for accpath in acceptable:
+            if myarg.startswith(path.join(accpath, user)):
+                return True
+        raise ValidationError('path %r not under %s' % (myarg,
+                              (' or '.join(path.join(x, user) for x in acceptable))))
+    return check
+
+
+def check_options(config, user, node):
+    if 'symlinks' in node.args.lower():
+        raise ValidationError('symlink options not allowed')
     return True