Index: fedd/federation/access.py
===================================================================
--- fedd/federation/access.py	(revision 027b87bcf2d08c18d5e45e080400fb93231b956d)
+++ fedd/federation/access.py	(revision 78f26681eb2754c621af4133819e3d800162618d)
@@ -124,75 +124,5 @@
 
 
-    def read_access(self, config, access_obj=None):
-        """
-	Read an access DB with filename config  of the form:
-	    (id, id, id) -> attribute, something
-	where the ids can be fedids, strings, or <any> or <none>, attribute is
-	the attribute to assign , and something is any set of charcters.  The
-	hash self.access is populated with mappings from those triples to the
-	results of access_obj being called on the remainder of the line (if
-	present).  If access_obj is not given, the string itself is entered in
-	the hash.  Additionally, a triple with <any> and <none> mapped to None
-	is entered in self.auth with the attribute given.
-
-	Parsing errors result in a self.parse_error exception being raised.
-	access_obj should throw that as well.
-        """
-        lineno=0
-        name_expr = "["+string.ascii_letters + string.digits + "\.\-_]+"
-        fedid_expr = "fedid:[" + string.hexdigits + "]+"
-        key_name = "(<ANY>|<NONE>|"+fedid_expr + "|"+ name_expr + ")"
-        access_re = re.compile('\('+key_name+'\s*,\s*'+key_name+'\s*,\s*'+
-                key_name+'\s*\)\s*->\s*([^,]+)\s*(.*)', re.IGNORECASE)
-
-        def parse_name(n):
-            if n.startswith('fedid:'): return fedid(hexstr=n[len('fedid:'):])
-            else: return n
-        
-        def auth_name(n):
-            if isinstance(n, basestring):
-                if n =='<any>' or n =='<none>': return None
-                else: return unicode(n)
-            else:
-                return n
-	def strip_comma(s):
-	    s = s.strip()
-	    if s.startswith(','):
-		s = s[1:].strip()
-	    return s
-
-	if access_obj is None:
-	    access_obj = lambda(x): "%s" % x
-
-        f = open(config, "r");
-	try:
-	    for line in f:
-		lineno += 1
-		line = line.strip();
-		if len(line) == 0 or line.startswith('#'):
-		    continue
-
-		# Access line (t, p, u) -> anything
-		m = access_re.match(line)
-		if m != None:
-		    access_key = tuple([ parse_name(x) \
-			    for x in m.group(1,2,3)])
-		    attribute = m.group(4)
-		    auth_key = tuple([ auth_name(x) for x in access_key])
-		    self.auth.set_attribute(auth_key, attribute)
-		    if len(m.group(5)) > 0:
-			access_val = access_obj(strip_comma(m.group(5)))
-			self.access[access_key] = access_val
-		    continue
-
-		# Nothing matched to here: unknown line - raise exception
-		f.close()
-		raise self.parse_error(
-			"Unknown statement at line %d of %s" % \
-			(lineno, config))
-	finally:
-	    if f: f.close()
-
-    def read_abac_access(self, fn, access_obj=None):
+    def read_access(self, fn, access_obj=None):
 	"""
 	Read an access DB of the form
@@ -228,15 +158,4 @@
 	finally:
 	    if f: f.close()
-
-
-    def get_users(self, obj):
-        """
-        Return a list of the IDs of the users in dict
-        """
-        if obj.has_key('user'):
-            return [ unpack_id(u['userID']) \
-                    for u in obj['user'] if u.has_key('userID') ]
-        else:
-            return None
 
     def write_state(self):
@@ -279,87 +198,10 @@
 
 
-
-    def permute_wildcards(self, a, p):
-        """Return a copy of a with various fields wildcarded.
-
-        The bits of p control the wildcards.  A set bit is a wildcard
-        replacement with the lowest bit being user then project then testbed.
-        """
-        if p & 1: user = ["<any>"]
-        else: user = a[2]
-        if p & 2: proj = "<any>"
-        else: proj = a[1]
-        if p & 4: tb = "<any>"
-        else: tb = a[0]
-
-        return (tb, proj, user)
-
-    def find_access(self, search):
-        """
-        Search the access DB for a match on this tuple.  Return the matching
-        access tuple and the user that matched.
-        
-        NB, if the initial tuple fails to match we start inserting wildcards in
-        an order determined by self.project_priority.  Try the list of users in
-        order (when wildcarded, there's only one user in the list).
-        """
-        if self.project_priority: perm = (0, 1, 2, 3, 4, 5, 6, 7)
-        else: perm = (0, 2, 1, 3, 4, 6, 5, 7)
-
-        for p in perm: 
-            s = self.permute_wildcards(search, p)
-            # s[2] is None on an anonymous, unwildcarded request
-            if s[2] != None:
-                for u in s[2]:
-                    if self.access.has_key((s[0], s[1], u)):
-                        return (self.access[(s[0], s[1], u)], u)
-            else:
-                if self.access.has_key(s):
-                    return (self.access[s], None)
-        return None, None
-
-    def lookup_access_base(self, req, fid):
-        """
-        Determine the allowed access for this request.  Return the access and
-        which fields are dynamic.
-
-        The fedid is needed to construct the request
-        """
-	user_re = re.compile("user:\s(.*)")
-	project_re = re.compile("project:\s(.*)")
-
-        # Search keys
-	tb = fid
-	user = [ user_re.findall(x)[0] for x in req.get('credential', []) \
-		if user_re.match(x)]
-	project = [ project_re.findall(x)[0] \
-		for x in req.get('credential', []) \
-		    if project_re.match(x)]
-
-	if len(project) == 1: project = project[0]
-	elif len(project) == 0: project = None
-	else: 
-	    raise service_error(service_error.req, 
-		    "More than one project credential")
-
-        # Confirm authorization
-        for u in user:
-            self.log.debug("[lookup_access] Checking access for %s" % \
-                    ((tb, project, u),))
-            if self.auth.check_attribute((tb, project, u), 'access'):
-                self.log.debug("[lookup_access] Access granted")
-                break
-            else:
-                self.log.debug("[lookup_access] Access Denied")
-        else:
-            raise service_error(service_error.access, "Access denied")
-
-        # This maps a valid user to the Emulab projects and users to use
-        found, user_match = self.find_access((tb, project, user))
-
-	return (found, (tb, project, user_match))
-        
-
     def get_handler(self, path, fid):
+	"""
+	This function is somewhat oddly named.  It doesn't get a handler, it
+	handles GETs.  Specifically, it handls https GETs for retrieving data
+	from the repository exported by the access server.
+	"""
 	self.log.info("Get handler %s %s" % (path, fid))
 	if self.auth.check_attribute(fid, path) and self.userconfdir:
Index: fedd/federation/emulab_access.py
===================================================================
--- fedd/federation/emulab_access.py	(revision 027b87bcf2d08c18d5e45e080400fb93231b956d)
+++ fedd/federation/emulab_access.py	(revision 78f26681eb2754c621af4133819e3d800162618d)
@@ -16,4 +16,5 @@
 
 from access import access_base
+from legacy_access import legacy_access
 
 from util import *
@@ -41,5 +42,5 @@
 fl.addHandler(nullHandler())
 
-class access(access_base):
+class access(access_base, legacy_access):
     """
     The implementation of access control based on mapping users to projects.
@@ -119,9 +120,9 @@
 	if self.auth_type == 'legacy':
 	    if accessdb:
-		self.read_access(accessdb, self.make_access_project)
+		self.legacy_read_access(accessdb, self.legacy_access_tuple)
 	elif self.auth_type == 'abac':
 	    self.auth = abac_authorizer(load=self.auth_dir)
 	    if accessdb:
-		self.read_abac_access(accessdb, self.make_abac_access_project)
+		self.read_access(accessdb, self.access_tuple)
 	else:
 	    raise service_error(service_error.internal, 
@@ -205,5 +206,5 @@
 
     @staticmethod
-    def make_access_project(str):
+    def legacy_access_tuple(str):
 	"""
 	Convert a string of the form (id[:resources:resouces], id, id) into a
@@ -235,8 +236,8 @@
 
     @staticmethod
-    def make_abac_access_project(str):
+    def access_tuple(str):
 	"""
 	Convert a string of the form (id, id) into an access_project.  This is
-	called by read_abac_access to convert to local attributes.  It returns
+	called by read_access to convert to local attributes.  It returns
 	a tuple of the form (project, user, user) where the two users are
 	always the same.
@@ -255,5 +256,5 @@
     # RequestAccess support routines
 
-    def lookup_access(self, req, fid):
+    def legacy_lookup_access(self, req, fid):
         """
 	Look up the local access control information mapped to this fedid and
@@ -270,5 +271,5 @@
         ru = None
         # This maps a valid user to the Emulab projects and users to use
-        found, match = self.lookup_access_base(req, fid)
+        found, match = self.legacy_lookup_access_base(req, fid)
 	tb, project, user = match
         
@@ -326,12 +327,16 @@
                 [ fid ]
 
-    def lookup_abac_access(self, req, fid): 
+    def lookup_access(self, req, fid): 
+	"""
+	Check all the attributes that this controller knows how to map and see
+	if the requester is allowed to use any of them.  If so return one.
+	"""
 	# Import request credentials into this (clone later??)
-	if self.auth.import_credentials(data_list=req.get('abac_credential', [])):
+	if self.auth.import_credentials(
+		data_list=req.get('abac_credential', [])):
 	    self.auth.save()
 
 	# Check every attribute that we know how to map and take the first
 	# success.
-	print "%s" %self.auth
 	for attr in (self.access.keys()):
 	    if self.auth.check_attribute(fid, attr):
@@ -491,7 +496,7 @@
 
 	if self.auth_type == "legacy":
+	    found, dyn, owners = self.legacy_lookup_access(req, fid)
+	elif self.auth_type == 'abac':
 	    found, dyn, owners = self.lookup_access(req, fid)
-	elif self.auth_type == 'abac':
-	    found, dyn, owners = self.lookup_abac_access(req, fid)
 	else:
 	    raise service_error(service_error.internal, 
Index: fedd/federation/legacy_access.py
===================================================================
--- fedd/federation/legacy_access.py	(revision 78f26681eb2754c621af4133819e3d800162618d)
+++ fedd/federation/legacy_access.py	(revision 78f26681eb2754c621af4133819e3d800162618d)
@@ -0,0 +1,198 @@
+#!/usr/local/bin/python
+
+import os,sys
+import stat # for chmod constants
+import re
+import random
+import string
+import copy
+import pickle
+import logging
+import subprocess
+
+from threading import *
+from M2Crypto.SSL import SSLError
+
+from util import *
+from allocate_project import allocate_project_local, allocate_project_remote
+from fedid import fedid, generate_fedid
+from authorizer import authorizer
+from service_error import service_error
+from remote_service import xmlrpc_handler, soap_handler, service_caller
+
+import httplib
+import tempfile
+from urlparse import urlparse
+
+import topdl
+import list_log
+import proxy_emulab_segment
+import local_emulab_segment
+
+
+# Make log messages disappear if noone configures a fedd logger
+class nullHandler(logging.Handler):
+    def emit(self, record): pass
+
+fl = logging.getLogger("fedd.access")
+fl.addHandler(nullHandler())
+
+class legacy_access:
+    """
+    This collects the legacy access control helpers in one place.
+    """
+
+    class parse_error(RuntimeError): pass
+
+    def __init__(self): pass
+
+    def legacy_read_access(self, config, access_obj=None):
+        """
+	Read an access DB with filename config  of the form:
+	    (id, id, id) -> attribute, something
+	where the ids can be fedids, strings, or <any> or <none>, attribute is
+	the attribute to assign , and something is any set of charcters.  The
+	hash self.access is populated with mappings from those triples to the
+	results of access_obj being called on the remainder of the line (if
+	present).  If access_obj is not given, the string itself is entered in
+	the hash.  Additionally, a triple with <any> and <none> mapped to None
+	is entered in self.auth with the attribute given.
+
+	Parsing errors result in a self.parse_error exception being raised.
+	access_obj should throw that as well.
+        """
+        lineno=0
+        name_expr = "["+string.ascii_letters + string.digits + "\.\-_]+"
+        fedid_expr = "fedid:[" + string.hexdigits + "]+"
+        key_name = "(<ANY>|<NONE>|"+fedid_expr + "|"+ name_expr + ")"
+        access_re = re.compile('\('+key_name+'\s*,\s*'+key_name+'\s*,\s*'+
+                key_name+'\s*\)\s*->\s*([^,]+)\s*(.*)', re.IGNORECASE)
+
+        def parse_name(n):
+            if n.startswith('fedid:'): return fedid(hexstr=n[len('fedid:'):])
+            else: return n
+        
+        def auth_name(n):
+            if isinstance(n, basestring):
+                if n =='<any>' or n =='<none>': return None
+                else: return unicode(n)
+            else:
+                return n
+	def strip_comma(s):
+	    s = s.strip()
+	    if s.startswith(','):
+		s = s[1:].strip()
+	    return s
+
+	if access_obj is None:
+	    access_obj = lambda(x): "%s" % x
+
+        f = open(config, "r");
+	try:
+	    for line in f:
+		lineno += 1
+		line = line.strip();
+		if len(line) == 0 or line.startswith('#'):
+		    continue
+
+		# Access line (t, p, u) -> anything
+		m = access_re.match(line)
+		if m != None:
+		    access_key = tuple([ parse_name(x) \
+			    for x in m.group(1,2,3)])
+		    attribute = m.group(4)
+		    auth_key = tuple([ auth_name(x) for x in access_key])
+		    self.auth.set_attribute(auth_key, attribute)
+		    if len(m.group(5)) > 0:
+			access_val = access_obj(strip_comma(m.group(5)))
+			self.access[access_key] = access_val
+		    continue
+
+		# Nothing matched to here: unknown line - raise exception
+		f.close()
+		raise self.parse_error(
+			"Unknown statement at line %d of %s" % \
+			(lineno, config))
+	finally:
+	    if f: f.close()
+
+    @staticmethod
+    def permute_wildcards(a, p):
+        """Return a copy of a with various fields wildcarded.
+
+        The bits of p control the wildcards.  A set bit is a wildcard
+        replacement with the lowest bit being user then project then testbed.
+        """
+        if p & 1: user = ["<any>"]
+        else: user = a[2]
+        if p & 2: proj = "<any>"
+        else: proj = a[1]
+        if p & 4: tb = "<any>"
+        else: tb = a[0]
+
+        return (tb, proj, user)
+
+    def legacy_find_access(self, search):
+        """
+        Search the access DB for a match on this tuple.  Return the matching
+        access tuple and the user that matched.
+        
+        NB, if the initial tuple fails to match we start inserting wildcards in
+        an order determined by self.project_priority.  Try the list of users in
+        order (when wildcarded, there's only one user in the list).
+        """
+        if self.project_priority: perm = (0, 1, 2, 3, 4, 5, 6, 7)
+        else: perm = (0, 2, 1, 3, 4, 6, 5, 7)
+
+        for p in perm: 
+            s = self.permute_wildcards(search, p)
+            # s[2] is None on an anonymous, unwildcarded request
+            if s[2] != None:
+                for u in s[2]:
+                    if self.access.has_key((s[0], s[1], u)):
+                        return (self.access[(s[0], s[1], u)], u)
+            else:
+                if self.access.has_key(s):
+                    return (self.access[s], None)
+        return None, None
+
+    def legacy_lookup_access_base(self, req, fid):
+        """
+        Determine the allowed access for this request.  Return the access and
+        which fields are dynamic.
+
+        The fedid is needed to construct the request
+        """
+	user_re = re.compile("user:\s(.*)")
+	project_re = re.compile("project:\s(.*)")
+
+        # Search keys
+	tb = fid
+	user = [ user_re.findall(x)[0] for x in req.get('credential', []) \
+		if user_re.match(x)]
+	project = [ project_re.findall(x)[0] \
+		for x in req.get('credential', []) \
+		    if project_re.match(x)]
+
+	if len(project) == 1: project = project[0]
+	elif len(project) == 0: project = None
+	else: 
+	    raise service_error(service_error.req, 
+		    "More than one project credential")
+
+        # Confirm authorization
+        for u in user:
+            self.log.debug("[lookup_access] Checking access for %s" % \
+                    ((tb, project, u),))
+            if self.auth.check_attribute((tb, project, u), 'access'):
+                self.log.debug("[lookup_access] Access granted")
+                break
+            else:
+                self.log.debug("[lookup_access] Access Denied")
+        else:
+            raise service_error(service_error.access, "Access denied")
+
+        # This maps a valid user to the Emulab projects and users to use
+        found, user_match = self.legacy_find_access((tb, project, user))
+
+	return (found, (tb, project, user_match))
