From: Thierry Parmentelat Date: Fri, 8 Oct 2010 14:19:35 +0000 (+0200) Subject: started to repair sfadump X-Git-Tag: sfa-1.0-2~1 X-Git-Url: http://git.onelab.eu/?p=sfa.git;a=commitdiff_plain;h=ea995a055eba04aedff577e86652abaaa5e881aa started to repair sfadump dumps can return strings --- diff --git a/sfa/client/sfadump.py b/sfa/client/sfadump.py old mode 100644 new mode 100755 index 6496ca64..7560819c --- a/sfa/client/sfadump.py +++ b/sfa/client/sfadump.py @@ -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() diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py index ab2119bc..e3f65c9f 100755 --- a/sfa/client/sfi.py +++ b/sfa/client/sfi.py @@ -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"): diff --git a/sfa/managers/slice_manager_pl.py b/sfa/managers/slice_manager_pl.py index 915b60cf..03bd9941 100644 --- a/sfa/managers/slice_manager_pl.py +++ b/sfa/managers/slice_manager_pl.py @@ -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: diff --git a/sfa/methods/GetSelfCredential.py b/sfa/methods/GetSelfCredential.py index fa8c3a1a..3d2bf8b4 100644 --- a/sfa/methods/GetSelfCredential.py +++ b/sfa/methods/GetSelfCredential.py @@ -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) diff --git a/sfa/plc/sfa-import-plc.py b/sfa/plc/sfa-import-plc.py index 2b409c39..9b280abc 100755 --- a/sfa/plc/sfa-import-plc.py +++ b/sfa/plc/sfa-import-plc.py @@ -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 diff --git a/sfa/plc/sfa-nuke-plc.py b/sfa/plc/sfa-nuke-plc.py index bdc38925..84360355 100755 --- a/sfa/plc/sfa-nuke-plc.py +++ b/sfa/plc/sfa-nuke-plc.py @@ -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() diff --git a/sfa/plc/sfaImport.py b/sfa/plc/sfaImport.py index 6147507e..015b680a 100644 --- a/sfa/plc/sfaImport.py +++ b/sfa/plc/sfaImport.py @@ -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) diff --git a/sfa/trust/auth.py b/sfa/trust/auth.py index b596d8d4..d0498e55 100644 --- a/sfa/trust/auth.py +++ b/sfa/trust/auth.py @@ -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) diff --git a/sfa/trust/certificate.py b/sfa/trust/certificate.py index 466cec89..f12c86b8 100644 --- a/sfa/trust/certificate.py +++ b/sfa/trust/certificate.py @@ -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 diff --git a/sfa/trust/credential.py b/sfa/trust/credential.py index 63233d2b..4e1fe0f1 100644 --- a/sfa/trust/credential.py +++ b/sfa/trust/credential.py @@ -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 diff --git a/sfa/trust/credential_legacy.py b/sfa/trust/credential_legacy.py index b868f2da..8ba90b29 100644 --- a/sfa/trust/credential_legacy.py +++ b/sfa/trust/credential_legacy.py @@ -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 diff --git a/sfa/trust/gid.py b/sfa/trust/gid.py index a880b52d..2f273a12 100644 --- a/sfa/trust/gid.py +++ b/sfa/trust/gid.py @@ -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 diff --git a/sfa/trust/hierarchy.py b/sfa/trust/hierarchy.py index 93970df6..790b10c3 100644 --- a/sfa/trust/hierarchy.py +++ b/sfa/trust/hierarchy.py @@ -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) = \ diff --git a/sfa/util/server.py b/sfa/util/server.py index c5c9841c..b5a966d9 100644 --- a/sfa/util/server.py +++ b/sfa/util/server.py @@ -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()