Index: fedd/federation/authorizer.py
===================================================================
--- fedd/federation/authorizer.py	(revision 09b1e9dd656dd429fa8f54ee9c2a5440dd47f6ce)
+++ fedd/federation/authorizer.py	(revision 7206e5a9a0196d4fdf2cea8dc635d31cd1fadf2c)
@@ -152,4 +152,7 @@
 	self.globals.discard(attr)
 
+    def import_credentials(self, file_list=None, data_list=None):
+	return False
+
     def __str__(self):
 	rv = ""
@@ -182,11 +185,11 @@
     """
 
-    clean_attr_re = re.compile('[^A-Za-z_]+')
+    clean_attr_re = re.compile('[^A-Za-z0-9_]+')
     cred_file_re = re.compile('.*\.der$')
     bad_name = authorizer_base.bad_name
     attribute_error = authorizer_base.attribute_error
-    ABAC.libabac_init()
-
-    def __init__(self, certs=None, me=None, key=None, loadfile=None):
+    class no_file(RuntimeError): pass
+
+    def __init__(self, certs=None, me=None, key=None, load=None):
 	self.creddy = '/usr/local/bin/creddy'
 	self.globals = set()
@@ -207,10 +210,37 @@
 	    self.context.load_directory(dir)
 
-	if loadfile:
-	    self.load(loadfile)
+	if load:
+	    self.save_dir = load
+	    self.load(load)
+	else:
+	    self.save_dir = None
 
     @staticmethod
     def clean_attr(attr):
 	return abac_authorizer.clean_attr_re.sub('_', attr)
+
+    def import_credentials(self, file_list=None, data_list=None):
+	if data_list:
+	    return any([self.import_credential(data=d) for d in data_list])
+	elif file_list:
+	    return any([self.import_credential(file=f) for f in file_list])
+	else:
+	    return False
+
+    def import_credential(self, file=None, data=None):
+	if data:
+	    if self.context.load_id_chunk(data) != ABAC.ABAC_CERT_SUCCESS:
+		return self.context.load_attribute_chunk(data) == \
+			ABAC.ABAC_CERT_SUCCESS
+	    else:
+		return True
+	elif file:
+	    if self.context.load_id_file(file) != ABAC.ABAC_CERT_SUCCESS:
+		return self.context.load_attribute_file(file) == \
+			ABAC.ABAC_CERT_SUCCESS
+	    else:
+		return True
+	else:
+	    return False
 
     def set_attribute(self, name=None, attr=None, cert=None):
@@ -219,4 +249,7 @@
 		raise abac_authorizer.bad_name(
 			"ABAC doesn't understand three-names")
+	    # Convert non-string attributes to strings
+	    if not isinstance(attr, basestring):
+		attr = "%s" % attr
 	    if self.me and self.key:
 		# Create a credential and insert it into context
@@ -261,4 +294,7 @@
 	    raise abac_authorizer.bad_name(
 		    "ABAC doesn't understand three-names")
+	# Convert non-string attributes to strings
+	if not isinstance(attr, basestring):
+	    attr = "%s" % attr
 	cattr = self.clean_attr(attr)
 	self.lock.acquire()
@@ -289,4 +325,7 @@
 		    "ABAC doesn't understand three-names")
 	else:
+	    # Convert non-string attributes to strings
+	    if not isinstance(attr, basestring):
+		attr = "%s" % attr
 	    # Naked attributes are attested by this principal
 	    if attr.find('.') == -1: 
@@ -297,5 +336,5 @@
 
 	    self.lock.acquire()
-	    proof, rv = self.context.query(a, name)
+	    rv, proof = self.context.query(a, "%s" % name)
 	    # XXX delete soon
 	    if not rv and attr in self.globals: rv = True
@@ -330,6 +369,13 @@
 	return rv
 
-    def save(self, dir):
-	self.lock.acquire()
+    def save(self, dir=None):
+	self.lock.acquire()
+	if dir:
+	    self.save_dir = dir
+	else:
+	    dir = self.save_dir
+	if dir is None:
+	    self.lock.release()
+	    raise abac_authorizer.no_file_error("No load directory specified")
 	try:
 	    if not os.access(dir, os.F_OK):
@@ -347,5 +393,6 @@
 	    if not os.access("%s/certs" %dir, os.F_OK):
 		os.mkdir("%s/certs" % dir)
-	    seenit = set()
+	    seenid = set()
+	    seenattr = set()
 
 	    #restore unpicklable state 
@@ -363,15 +410,16 @@
 		# NB: file naming conventions matter here.  The trailing_ID and
 		# _attr are required by ABAC.COntext.load_directory()
-		if id not in seenit:
+		if id and id not in seenid:
 		    f = open("%s/certs/ID_%03d_ID.der" % (dir, ii), "w")
-		    print >>f, id
+		    f.write(id)
 		    f.close()
 		    ii += 1
-		    seenit.add(id)
-		if attr:
+		    seenid.add(id)
+		if attr and attr not in seenattr:
 		    f = open("%s/certs/attr_%03d_attr.der" % (dir, ai), "w")
-		    print >>f, attr
+		    f.write(attr)
 		    f.close()
 		    ai += 1
+		    seenattr.add(attr)
 	except EnvironmentError, e:
 	    # If we've mislaid self.lock, release lock (they're the same object)
@@ -386,6 +434,13 @@
 	self.lock.release()
 
-    def load(self, dir):
-	self.lock.acquire()
+    def load(self, dir=None):
+	self.lock.acquire()
+	if dir:
+	    self.save_dir = dir
+	else:
+	    dir = self.save_dir
+	if dir is None:
+	    self.lock.release()
+	    raise abac_authorizer.no_file_error("No load directory specified")
 	try:
 	    if os.access("%s/state" % dir, os.R_OK):
@@ -402,4 +457,5 @@
 		self.context.load_id_file(self.me)
 	    self.context.load_directory("%s/certs" % dir)
+	    self.save_dir = dir
 	except EnvironmentError, e:
 	    self.lock.release()
