started to repair sfadump
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Fri, 8 Oct 2010 14:19:35 +0000 (16:19 +0200)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Fri, 8 Oct 2010 14:19:35 +0000 (16:19 +0200)
dumps can return strings

14 files changed:
sfa/client/sfadump.py [changed mode: 0644->0755]
sfa/client/sfi.py
sfa/managers/slice_manager_pl.py
sfa/methods/GetSelfCredential.py
sfa/plc/sfa-import-plc.py
sfa/plc/sfa-nuke-plc.py
sfa/plc/sfaImport.py
sfa/trust/auth.py
sfa/trust/certificate.py
sfa/trust/credential.py
sfa/trust/credential_legacy.py
sfa/trust/gid.py
sfa/trust/hierarchy.py
sfa/util/server.py

old mode 100644 (file)
new mode 100755 (executable)
index 6496ca6..7560819
@@ -1,6 +1,4 @@
 #! /usr/bin/env python
-# $Id$
-# $URL$
 from __future__ import with_statement
 
 import sys
@@ -14,21 +12,27 @@ from sfa.trust.certificate import Certificate
 from sfa.trust.credential import Credential
 from sfa.util.record import SfaRecord
 from sfa.util.rspec import RSpec
+from sfa.util.sfalogging import sfa_logger, sfa_logger_goes_to_console
 
 def determine_sfa_filekind(fn):
-    cert = Certificate(filename = fn)
-
-    data = cert.get_data()
-    if data:
-        dict = xmlrpclib.loads(data)[0][0]
-    else:
-        dict = {}
-
-    if "gidCaller" in dict:
-        return "credential"
-
-    if "uuid" in dict:
-        return "gid"
+    try:
+        cert = Certificate(filename = fn)
+        return 'certificate'
+    except:
+        pass
+
+    try:
+        cred=Credential(filename=fn)
+        return 'credential'
+    except:
+        pass
+
+    # to be completed
+#    if "gidCaller" in dict:
+#        return "credential"
+#
+#    if "uuid" in dict:
+#        return "gid"
 
     return "unknown"
 
@@ -54,41 +58,48 @@ def extract_gids(cred, extract_parents):
    if gidObject and ((gidCaller == None) or (gidCaller.get_hrn() != gidObject.get_hrn())):
        save_gid(gidObject)
 
-   if extract_parents:
-       parent = cred.get_parent()
-       if parent:
-           extract_gids(parent, extract_parents)
-
-def create_parser():
-   # Generate command line parser
-   parser = OptionParser(usage="%prog [options] filename")
-
-   parser.add_option("-e", "--extractgids", action="store_true", dest="extract_gids", default=False, help="Extract GIDs from credentials")
-   parser.add_option("-p", "--dumpparents", action="store_true", dest="dump_parents", default=False, help="Show parents")
-
-   return parser
+   # no such method Credential.get_parent
+#   if extract_parents:
+#       parent = cred.get_parent()
+#       if parent:
+#           extract_gids(parent, extract_parents)
+
+def handle_input (filename, options):
+    
+    kind = determine_sfa_filekind(filename)
+
+    if kind=="certificate":
+        cert=Certificate (filename=filename)
+#        cert.dump(dump_parents=options.dump_parents)
+        cert.dump()
+    elif kind=="credential":
+        cred = Credential(filename = filename)
+        cred.dump(dump_parents = options.dump_parents)
+        if options.extract_gids:
+            extract_gids(cred, extract_parents = options.dump_parents)
+    elif kind=="gid":
+        gid = Gid(filename = filename)
+        gid.dump(dump_parents = options.dump_parents)
+    else:
+        print "%s: unknown filekind '%s'"% (filename,kind)
 
 def main():
-   parser = create_parser()
-   (options, args) = parser.parse_args()
-
-   if len(args) <= 0:
-        print "No filename given. Use -h for help."
-        return -1
-
-   filename = args[0]
-   kind = determine_sfa_filekind(filename)
-
-   if kind=="credential":
-       cred = Credential(filename = filename)
-       cred.dump(dump_parents = options.dump_parents)
-       if options.extract_gids:
-           extract_gids(cred, extract_parents = options.dump_parents)
-   elif kind=="gid":
-       gid = Gid(filename = filename)
-       gid.dump(dump_parents = options.dump_parents)
-   else:
-       print "unknown filekind", kind
+    sfa_logger_goes_to_console()
+    usage = """%prog file1 [ .. filen]
+display info on input files"""
+    parser = OptionParser(usage=usage)
+
+    parser.add_option("-e", "--extractgids", action="store_true", dest="extract_gids", default=False, help="Extract GIDs from credentials")
+    parser.add_option("-p", "--dumpparents", action="store_true", dest="dump_parents", default=False, help="Show parents")
+    parser.add_option("-v", "--verbose", action='count', dest='verbose', default=0)
+    (options, args) = parser.parse_args()
+
+    sfa_logger().setLevelFromOptVerbose(options.verbose)
+    if len(args) <= 0:
+        parser.print_help()
+        sys.exit(1)
+    for f in args: 
+        handle_input(f,options)
 
 if __name__=="__main__":
    main()
index ab2119b..e3f65c9 100755 (executable)
@@ -940,10 +940,7 @@ class Sfi:
 
         self.set_servers()
     
-        self.logger.info("Command %s" % command)
-        self.logger.info("dir %s, user %s, auth %s, reg %s, sm %s" % (
-                self. options.sfi_dir, self.options.user,self.options.auth,
-                self.options.registry, self.options.sm))
+        self.logger.info("Command=%s" % command)
         if command in ("resources"):
             self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
         elif command in ("list", "show", "remove"):
index 915b60c..03bd994 100644 (file)
@@ -1,14 +1,15 @@
 ### $Id: slices.py 15842 2009-11-22 09:56:13Z anil $
 ### $URL: https://svn.planet-lab.org/svn/sfa/trunk/sfa/plc/slices.py $
 
-import datetime
-import time
-import traceback
 import sys
-from copy import deepcopy
-from lxml import etree
+import time,datetime
 from StringIO import StringIO
 from types import StringTypes
+from copy import deepcopy
+from copy import copy
+from lxml import etree
+
+from sfa.util.sfalogging import sfa_logger
 from sfa.util.rspecHelper import merge_rspecs
 from sfa.util.namespace import *
 from sfa.util.rspec import *
@@ -22,7 +23,6 @@ from sfa.trust.credential import Credential
 from sfa.util.threadmanager import ThreadManager
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol     
 import sfa.plc.peers as peers
-from copy import copy
 
 def get_version():
     version = {}
@@ -365,6 +365,7 @@ def get_rspec(api, creds, options):
                 for request in root.iterfind("./request"):
                     rspec.append(deepcopy(request))
     
+    sfa_logger().debug('get_rspec: rspec=%r'%rspec)
     rspec =  etree.tostring(rspec, xml_declaration=True, pretty_print=True)
     # cache the result
     if api.cache and not xrn:
index fa8c3a1..3d2bf8b 100644 (file)
@@ -67,6 +67,8 @@ class GetSelfCredential(Method):
         # authenticate the certificate against the gid in the db
         certificate = Certificate(string=cert)
         if not certificate.is_pubkey(gid.get_pubkey()):
+            self.api.logger.info("ConnectionKeyGIDMismatch, CERT: %s"%certificate.get_pubkey().get_pubkey_string())
+            self.api.logger.info("ConnectionKeyGIDMismatch, GID: %s"%gid.get_pubkey().get_pubkey_string())
             raise ConnectionKeyGIDMismatch(gid.get_subject())
         
         return manager.get_credential(self.api, xrn, type, is_self=True)
index 2b409c3..9b280ab 100755 (executable)
@@ -137,7 +137,7 @@ def main():
     # start importing 
     for site in sites:
         site_hrn = interface_hrn + "." + site['login_base']
-        print "Importing site: %s" % site_hrn
+        sfa_logger().info("Importing site: %s" % site_hrn)
 
         # import if hrn is not in list of existing hrns or if the hrn exists
         # but its not a site record
index bdc3892..8436035 100755 (executable)
@@ -7,27 +7,39 @@
 # is not purged by this tool and may be deleted by a command like 'rm'.
 ##
 
-import getopt
 import sys
+import os
+from optparse import OptionParser
 
 from sfa.trust.hierarchy import *
 from sfa.util.record import *
 from sfa.util.table import SfaTable
 from sfa.util.sfalogging import sfa_logger_goes_to_import,sfa_logger
 
-def process_options():
-
-   (options, args) = getopt.getopt(sys.argv[1:], '', [])
-   for opt in options:
-       name = opt[0]
-       val = opt[1]
-
 def main():
-    process_options()
-    sfa_logger_goes_to_import()
-    sfa_logger().info("Purging SFA records from database")
-    table = SfaTable()
-    table.sfa_records_purge()
-
+   usage="%prog: trash the registry DB (the 'sfa' table in the 'planetlab5' database)"
+   parser = OptionParser(usage=usage)
+   parser.add_option('-f','--file-system',dest='clean_fs',action='store_true',default=False,
+                     help='Clean up the /var/lib/sfa/authorities area as well')
+   (options,args)=parser.parse_args()
+   if args:
+      parser.print_help()
+      sys.exit(1)
+   sfa_logger_goes_to_import()
+   sfa_logger().info("Purging SFA records from database")
+   table = SfaTable()
+   table.sfa_records_purge()
+   if options.clean_fs:
+      # just remove all files that do not match 'server.key' or 'server.cert'
+      preserved_files = [ 'server.key', 'server.cert']
+      for (dir,_,files) in os.walk('/var/lib/sfa/authorities'):
+         for file in files:
+            if file in preserved_files: continue
+            path=dir+os.sep+file
+            os.unlink(path)
+            if not os.path.exists(path):
+               sfa_logger().info("Unlinked file %s"%path)
+            else:
+               sfa_logger().error("Could not unlink file %s"%path)
 if __name__ == "__main__":
-    main()
+   main()
index 6147507..015b680 100644 (file)
@@ -80,7 +80,7 @@ class sfaImport:
 
         # create the authority if it doesnt already exist 
         if not self.AuthHierarchy.auth_exists(urn):
-            self.logger.info("Import: creating top level authorites")
+            self.logger.info("Import: creating top level authorities")
             self.AuthHierarchy.create_auth(urn)
         
         # create the db record if it doesnt already exist    
@@ -102,7 +102,7 @@ class sfaImport:
         if len(hrn) > 64:
             hrn = hrn[:64]
 
-        self.logger.info("Import: importing person " + hrn)
+        self.logger.info("Import: person " + hrn)
         key_ids = []
         if 'key_ids' in person and person['key_ids']:
             key_ids = person["key_ids"]
@@ -115,7 +115,7 @@ class sfaImport:
                 pkey = Keypair(create=True)
         else:
             # the user has no keys
-            self.logger.info("   person " + hrn + " does not have a PL public key")
+            self.logger.warning("Import: person %s does not have a PL public key"%hrn)
             # if a key is unavailable, then we still need to put something in the
             # user's GID. So make one up.
             pkey = Keypair(create=True)
@@ -140,11 +140,11 @@ class sfaImport:
         slicename = _cleanup_string(slicename)
 
         if not slicename:
-            self.logger.error("Import_Slice: failed to parse slice name " + slice['name'])
+            self.logger.error("Import: failed to parse slice name " + slice['name'])
             return
 
         hrn = parent_hrn + "." + slicename
-        self.logger.info("Import: importing slice " + hrn)
+        self.logger.info("Import: slice " + hrn)
 
         pkey = Keypair(create=True)
         urn = hrn_to_urn(hrn, 'slice')
@@ -166,11 +166,11 @@ class sfaImport:
         nodename = _cleanup_string(nodename)
         
         if not nodename:
-            self.logger.error("Import_node: failed to parse node name " + node['hostname'])
+            self.logger.error("Import: failed to parse node name " + node['hostname'])
             return
 
         hrn = parent_hrn + "." + nodename
-        self.logger.info("Import: importing node " + hrn)
+        self.logger.info("Import: node %s" % hrn)
         # ASN.1 will have problems with hrn's longer than 64 characters
         if len(hrn) > 64:
             hrn = hrn[:64]
@@ -210,7 +210,7 @@ class sfaImport:
                 hrn = ".".join([parent_hrn, "internet2", sitename])
 
         urn = hrn_to_urn(hrn, 'authority')
-        self.logger.info("Import: importing site " + hrn)
+        self.logger.info("Import: site " + hrn)
 
         # create the authority
         if not self.AuthHierarchy.auth_exists(urn):
@@ -238,5 +238,5 @@ class sfaImport:
         table = SfaTable()
         record_list = table.find({'type': type, 'hrn': hrn})
         for record in record_list:
-            self.logger.info("Import: Removing record %s %s" % (type, hrn))
+            self.logger.info("Import: removing record %s %s" % (type, hrn))
             table.remove(record)        
index b596d8d..d0498e5 100644 (file)
@@ -1,10 +1,7 @@
 #
 # SfaAPI authentication 
 #
-### $Id$
-### $URL$
-#
-
+import sys
 
 from sfa.trust.certificate import Keypair, Certificate
 from sfa.trust.credential import Credential
@@ -14,7 +11,8 @@ from sfa.trust.hierarchy import Hierarchy
 from sfa.util.config import *
 from sfa.util.namespace import *
 from sfa.util.sfaticket import *
-import sys
+
+from sfa.util.sfalogging import sfa_logger
 
 class Auth:
     """
@@ -38,11 +36,14 @@ class Auth:
         valid = []
         if not isinstance(creds, list):
             creds = [creds]
+        sfa_logger().debug("Auth.checkCredentials with %d creds"%len(creds))
         for cred in creds:
             try:
                 self.check(cred, operation, hrn)
                 valid.append(cred)
             except:
+                cred_obj=Credential(string=cred)
+                sfa_logger().debug("failed to validate credential - dump="+cred_obj.dump_string(dump_parents=True))
                 error = sys.exc_info()[:2]
                 continue
             
@@ -57,7 +58,7 @@ class Auth:
         Check the credential against the peer cert (callerGID included 
         in the credential matches the caller that is connected to the 
         HTTPS connection, check if the credential was signed by a 
-        trusted cert and check if the credential is allowd to perform 
+        trusted cert and check if the credential is allowed to perform 
         the specified operation.    
         """
         self.client_cred = Credential(string = cred)
index 466cec8..f12c86b 100644 (file)
@@ -459,9 +459,11 @@ class Certificate:
     # Get an X509 extension from the certificate
 
     def get_extension(self, name):
+
         # pyOpenSSL does not have a way to get extensions
         m2x509 = X509.load_cert_string(self.save_to_string())
         value = m2x509.get_ext(name).get_value()
+        
         return value
 
     ##
@@ -582,33 +584,69 @@ class Certificate:
 
         # verify expiration time
         if self.cert.has_expired():
-            sfa_logger().debug("verify_chain: our certificate has expired")
+            sfa_logger().debug("verify_chain: NO our certificate has expired")
             raise CertExpired(self.get_subject(), "client cert")   
         
         # if this cert is signed by a trusted_cert, then we are set
         for trusted_cert in trusted_certs:
             if self.is_signed_by_cert(trusted_cert):
-                sfa_logger().debug("verify_chain: cert %s signed by trusted cert %s"%(
-                        self.get_subject(), trusted_cert.get_subject()))
                 # verify expiration of trusted_cert ?
                 if not trusted_cert.cert.has_expired():
+                    sfa_logger().debug("verify_chain: YES cert %s signed by trusted cert %s"%(
+                            self.get_subject(), trusted_cert.get_subject()))
                     return trusted_cert
                 else:
-                    sfa_logger().debug("verify_chain: cert %s is signed by trusted_cert %s, but this is expired..."%(
+                    sfa_logger().debug("verify_chain: NO cert %s is signed by trusted_cert %s, but this is expired..."%(
                             self.get_subject(),trusted_cert.get_subject()))
+                    raise CertExpired(self.get_subject(),"trusted_cert %s"%trusted_cert.get_subject())
 
         # if there is no parent, then no way to verify the chain
         if not self.parent:
-            sfa_logger().debug("verify_chain: %r has no parent"%self.get_subject())
+            sfa_logger().debug("verify_chain: NO %s has no parent and is not in trusted roots"%self.get_subject())
             raise CertMissingParent(self.get_subject())
 
         # if it wasn't signed by the parent...
         if not self.is_signed_by_cert(self.parent):
-            sfa_logger().debug("verify_chain: %r is not signed by parent"%self.get_subject())
+            sfa_logger().debug("verify_chain: NO %s is not signed by parent"%self.get_subject())
             return CertNotSignedByParent(self.get_subject())
 
         # if the parent isn't verified...
-        sfa_logger().debug("verify_chain: with subject=%r, referring to parent, subj=%r",self.get_subject(),self.parent.get_subject())
+        sfa_logger().debug("verify_chain: .. %s, -> verifying parent %s",self.get_subject(),self.parent.get_subject())
         self.parent.verify_chain(trusted_certs)
 
         return
+
+    ### more introspection
+    def get_extensions(self):
+        # pyOpenSSL does not have a way to get extensions
+        triples=[]
+        m2x509 = X509.load_cert_string(self.save_to_string())
+        nb_extensions=m2x509.get_ext_count()
+        sfa_logger().debug("X509 had %d extensions"%nb_extensions)
+        for i in range(nb_extensions):
+            ext=m2x509.get_ext_at(i)
+            triples.append( (ext.get_name(), ext.get_value(), ext.get_critical(),) )
+        return triples
+
+    def get_data_names(self):
+        return self.data.keys()
+
+    def get_all_datas (self):
+        triples=self.get_extensions()
+        for name in self.get_data_names(): 
+            triples.append( (name,self.get_data(name),'data',) )
+        return triples
+
+    def dump (self, *args, **kwargs):
+        print self.dump_string(*args, **kwargs)
+
+    def dump_string (self):
+        result = ""
+        result += "Certificate for %s\n"%self.get_subject()
+        result += "Issued by %s\n"%self.get_issuer()
+        for (n,v,c) in self.get_all_datas():
+            if c=='data':
+                result += "   data: %s=%s\n"%(n,v)
+            else:
+                result += "    ext: %s=%s (%s)\n"%(n,v,c)
+        return result
index 63233d2..4e1fe0f 100644 (file)
@@ -828,23 +828,25 @@ class Credential(object):
     #
     # @param dump_parents If true, also dump the parent certificates
 
-    def dump(self, dump_parents=False):
-        print "CREDENTIAL", self.get_subject()
+    def dump (self, *args, **kwargs):
+        print self.dump_string(*args, **kwargs)
 
-        print "      privs:", self.get_privileges().save_to_string()
-
-        print "  gidCaller:"
+    def dump_string(self, dump_parents=False):
+        result=""
+        result += "CREDENTIAL %s\n" % self.get_subject() 
+        result += "      privs: %s\n" % self.get_privileges().save_to_string()
         gidCaller = self.get_gid_caller()
         if gidCaller:
-            gidCaller.dump(8, dump_parents)
+            result += "  gidCaller:\n"
+            result += gidCaller.dump_string(8, dump_parents)
 
-        print "  gidObject:"
         gidObject = self.get_gid_object()
         if gidObject:
-            gidObject.dump(8, dump_parents)
-
+            result += "  gidObject:\n"
+            result += gidObject.dump_string(8, dump_parents)
 
         if self.parent and dump_parents:
-            print "PARENT",
-            self.parent.dump_parents()
+            result += "PARENT"
+            result += self.parent.dump_string(dump_parents)
+        return result
 
index b868f2d..8ba90b2 100644 (file)
@@ -223,24 +223,29 @@ class CredentialLegacy(Certificate):
     #
     # @param dump_parents If true, also dump the parent certificates
 
-    def dump(self, dump_parents=False):
-        print "CREDENTIAL", self.get_subject()
+    def dump(self, *args, **kwargs):
+        print self.dump_string(*args,**kwargs)
 
-        print "      privs:", self.get_privileges().save_to_string()
+    def dump_string(self, dump_parents=False):
+        result=""
+        result += "CREDENTIAL %s\n" % self.get_subject()
+
+        result += "      privs: %s\n" % self.get_privileges().save_to_string()
 
-        print "  gidCaller:"
         gidCaller = self.get_gid_caller()
         if gidCaller:
+            result += "  gidCaller:\n"
             gidCaller.dump(8, dump_parents)
 
-        print "  gidObject:"
         gidObject = self.get_gid_object()
         if gidObject:
-            gidObject.dump(8, dump_parents)
+            result += "  gidObject:\n"
+            result += gidObject.dump_string(8, dump_parents)
 
-        print "   delegate:", self.get_delegate()
+        result += "   delegate: %s" % self.get_delegate()
 
         if self.parent and dump_parents:
-           print "PARENT",
-           self.parent.dump(dump_parents)
+            result += "PARENT\n"
+            result += self.parent.dump_string(dump_parents)
 
+        return result
index a880b52..2f273a1 100644 (file)
@@ -178,14 +178,19 @@ class GID(Certificate):
     # @param indent specifies a number of spaces to indent the output
     # @param dump_parents If true, also dump the parents of the GID
 
-    def dump(self, indent=0, dump_parents=False):
-        print " "*indent, " hrn:", self.get_hrn()
-        print " "*indent, " urn:", self.get_urn()
-        print " "*indent, "uuid:", self.get_uuid()
+    def dump(self, *args, **kwargs):
+        print self.dump_string(*args,**kwargs)
+
+    def dump_string(self, indent=0, dump_parents=False):
+        result=""
+        result += " "*indent + "hrn:" + self.get_hrn() +"\n"
+        result += " "*indent + "urn:" + self.get_urn() +"\n"
+        result += " "*indent + "uuid:" + str(self.get_uuid()) + "\n"
 
         if self.parent and dump_parents:
-            print " "*indent, "parent:"
-            self.parent.dump(indent+4, dump_parents)
+            result += " "*indent + "parent:\n"
+            result += self.parent.dump_string(indent+4, dump_parents)
+        return result
 
     ##
     # Verify the chain of authenticity of the GID. First perform the checks
index 93970df..790b10c 100644 (file)
@@ -206,8 +206,8 @@ class Hierarchy:
 
     def get_auth_info(self, xrn):
         hrn, type = urn_to_hrn(xrn)
-        sfa_logger().debug("Hierarchy: xrn=%s, getting authority for hrn=%s"%(xrn,hrn))
         if not self.auth_exists(hrn):
+            sfa_logger().warning("Hierarchy: mising authority - xrn=%s, hrn=%s"%(xrn,hrn))
             raise MissingAuthority(hrn)
 
         (directory, gid_filename, privkey_filename, dbinfo_filename) = \
index c5c9841..b5a966d 100644 (file)
@@ -111,7 +111,7 @@ class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
         except Exception, fault:
             # This should only happen if the module is buggy
             # internal error, report as HTTP server error
-            sfa_error.log_exc("server.do_POST")
+            sfa_logger().log_exc("server.do_POST")
             response = self.api.prepare_response(fault)
             #self.send_response(500)
             #self.end_headers()