validate credential against RelaxNG schema
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Mon, 22 Nov 2010 17:12:01 +0000 (12:12 -0500)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Mon, 22 Nov 2010 17:12:01 +0000 (12:12 -0500)
config/default_config.xml
setup.py
sfa.spec
sfa/trust/auth.py
sfa/trust/credential.py

index ce5ec40..899d173 100644 (file)
@@ -24,6 +24,12 @@ Thierry Parmentelat
          <description>The human readable name for this interface.</description>
        </variable>
 
+    <variable id="credential_schema" type="string">
+      <name>Credential Schema</name>
+      <value>/etc/sfa/credential.rng</value>
+      <description>The path to the default credential schema</description>
+    </variable>
+
        <variable id="api_debug" type="boolean">
          <name>Debug</name>
          <value>false</value>
index f0f89a4..897e3cd 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -54,7 +54,8 @@ data_files = [('/etc/sfa/', [ 'config/aggregates.xml',
                               'config/registries.xml',
                               'config/default_config.xml',
                               'config/sfi_config',
-                              'sfa/managers/pl/pl.rng']),
+                              'sfa/managers/pl/pl.rng',
+                              'sfa/trust/credential.rng']),
               ('/etc/sfatables/matches/', glob('sfatables/matches/*.xml')),
               ('/etc/sfatables/targets/', glob('sfatables/targets/*.xml')),
               ('/etc/init.d/', ['sfa/init.d/sfa', 'sfa/init.d/sfa-cm'])]
index 27158db..96663d3 100644 (file)
--- a/sfa.spec
+++ b/sfa.spec
@@ -131,6 +131,7 @@ rm -rf $RPM_BUILD_ROOT
 %config (noreplace) /etc/sfa/registries.xml
 /etc/init.d/sfa
 /etc/sfa/pl.rng
+/etc/sfa/credential.rng
 %{_bindir}/sfa-config-tty
 %{_bindir}/sfa-import-plc.py*
 %{_bindir}/sfa-clean-peer-records.py*
index 0b76d9e..e74dc16 100644 (file)
@@ -79,7 +79,7 @@ class Auth:
                 raise InsufficientRights(operation)
 
         if self.trusted_cert_list:
-            self.client_cred.verify(self.trusted_cert_file_list)
+            self.client_cred.verify(self.trusted_cert_file_list, self.config.SFA_CREDENTIAL_SCHEMA)
         else:
            raise MissingTrustedRoots(self.config.get_trustedroots_dir())
        
index 5aa7631..5478b03 100644 (file)
@@ -34,7 +34,8 @@ import datetime
 from tempfile import mkstemp
 from xml.dom.minidom import Document, parseString
 from dateutil.parser import parse
-
+from lxml import etree
+from StringIO import StringIO 
 from sfa.util.faults import *
 from sfa.util.sfalogging import sfa_logger
 from sfa.trust.certificate import Keypair
@@ -649,11 +650,24 @@ class Credential(object):
     #   must be done elsewhere
     #
     # @param trusted_certs: The certificates of trusted CA certificates
-    def verify(self, trusted_certs):
+    # @param schema: The RelaxNG schema to validate the credential against 
+    def verify(self, trusted_certs, schema=None):
         if not self.xml:
             self.decode()        
+        
+        # validate against RelaxNG schema
+        if not self.legacy:
+            if schema and os.path.exists(schema):
+                tree = etree.parse(StringIO(self.xml))
+                schema_doc = etree.parse(schema)
+                relaxng = etree.RelaxNG(schema_doc)
+                if not relaxng(tree):
+                    error = relaxng.error_log.last_error
+                    message = "%s (line %s)" % (error.message, error.line)
+                    raise CredentialNotVerifiable(message) 
+            
 
-#        trusted_cert_objects = [GID(filename=f) for f in trusted_certs]
+#       trusted_cert_objects = [GID(filename=f) for f in trusted_certs]
         trusted_cert_objects = []
         ok_trusted_certs = []
         for f in trusted_certs:
@@ -674,6 +688,7 @@ class Credential(object):
             if self.legacy.object_gid:
                 self.legacy.object_gid.verify_chain(trusted_cert_objects)
             return True
+
         
         # make sure it is not expired
         if self.get_expiration() < datetime.datetime.utcnow():