From 73e68cb7d9d0a0966832d610f516e390fbf534c6 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Thu, 10 Dec 2015 09:57:35 +0100 Subject: [PATCH] more aggressively check for xmlsec1 being installed, raise an exception otherwise --- sfa/trust/credential.py | 41 +++++++++++++++++++++++++------------ sfa/trust/speaksfor_util.py | 12 +++++++---- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/sfa/trust/credential.py b/sfa/trust/credential.py index 59623f48..4c563183 100644 --- a/sfa/trust/credential.py +++ b/sfa/trust/credential.py @@ -299,16 +299,25 @@ class Credential(object): else: self.xml = str self.decode() - - # Find an xmlsec1 path - self.xmlsec_path = '' - paths = ['/usr/bin','/usr/local/bin','/bin','/opt/bin','/opt/local/bin'] - for path in paths: - if os.path.isfile(path + '/' + 'xmlsec1'): - self.xmlsec_path = path + '/' + 'xmlsec1' - break - if not self.xmlsec_path: - logger.warn("Could not locate binary for xmlsec1 - SFA will be unable to sign stuff !!") + # not strictly necessary but won't hurt either + self.get_xmlsec1_path() + + @staticmethod + def get_xmlsec1_path(): + if not getattr(Credential, 'xmlsec1_path', None): + # Find a xmlsec1 binary path + Credential.xmlsec1_path = '' + paths = ['/usr/bin', '/usr/local/bin', '/bin', '/opt/bin', '/opt/local/bin'] + try: paths += os.getenv('PATH').split(':') + except: pass + for path in paths: + xmlsec1 = os.path.join(path, 'xmlsec1') + if os.path.isfile(xmlsec1): + Credential.xmlsec1_path = xmlsec1 + break + if not Credential.xmlsec1_path: + logger.error("Could not locate required binary 'xmlsec1' - SFA will be unable to sign stuff !!") + return Credential.xmlsec1_path def get_subject(self): if not self.gidObject: @@ -683,8 +692,11 @@ class Credential(object): # Call out to xmlsec1 to sign it ref = 'Sig_%s' % self.get_refid() filename = self.save_to_random_tmp_file() - command='%s --sign --node-id "%s" --privkey-pem %s,%s %s' \ - % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename) + xmlsec1 = self.get_xmlsec1_path() + if not xmlsec1: + raise Exception("Could not locate required 'xmlsec1' program") + command = '%s --sign --node-id "%s" --privkey-pem %s,%s %s' \ + % (xmlsec1, ref, self.issuer_privkey, ",".join(gid_files), filename) # print 'command',command signed = os.popen(command).read() os.remove(filename) @@ -881,7 +893,10 @@ class Credential(object): #cert_args = " ".join(['--trusted-pem %s' % x for x in trusted_certs]) #command = '{} --verify --node-id "{}" {} {} 2>&1'.\ # format(self.xmlsec_path, ref, cert_args, filename) - command = [ self.xmlsec_path, '--verify', '--node-id', ref ] + xmlsec1 = cred.get_xmlsec1_path() + if not xmlsec1: + raise Exception("Could not locate required 'xmlsec1' program") + command = [ xmlsec1, '--verify', '--node-id', ref ] for trusted in trusted_certs: command += ["--trusted-pem", trusted ] command += [ filename ] diff --git a/sfa/trust/speaksfor_util.py b/sfa/trust/speaksfor_util.py index eaeecf0f..af2f8b54 100644 --- a/sfa/trust/speaksfor_util.py +++ b/sfa/trust/speaksfor_util.py @@ -167,7 +167,10 @@ def verify_speaks_for(cred, tool_gid, speaking_for_urn, for x in trusted_roots: cert_args += ['--trusted-pem', x.filename] # FIXME: Why do we not need to specify the --node-id option as credential.py does? - xmlsec1_args = [cred.xmlsec_path, '--verify'] + cert_args + [ cred_file] + xmlsec1 = cred.get_xmlsec1_path() + if not xmlsec1: + raise Exception("Could not locate required 'xmlsec1' program") + xmlsec1_args = [xmlsec1, '--verify'] + cert_args + [ cred_file] output = run_subprocess(xmlsec1_args, stdout=None, stderr=subprocess.PIPE) os.unlink(cred_file) if output != 0: @@ -306,7 +309,6 @@ def create_sign_abaccred(tool_gid, user_gid, ma_gid, user_key_file, cred_filenam print "Created ABAC credential: '%s' in file %s" % \ (cred.pretty_cred(), cred_filename) -# FIXME: Assumes xmlsec1 is on path # FIXME: Assumes signer is itself signed by an 'ma_gid' that can be trusted def create_speaks_for(tool_gid, user_gid, ma_gid, \ user_key_file, cred_filename, dur_days=365): @@ -366,8 +368,10 @@ def create_speaks_for(tool_gid, user_gid, ma_gid, \ # --output signed.xml tosign.xml pems = "%s,%s,%s" % (user_key_file, user_gid.get_filename(), ma_gid.get_filename()) - # FIXME: assumes xmlsec1 is on path - cmd = ['xmlsec1', '--sign', '--privkey-pem', pems, + xmlsec1 = cred.get_xmlsec1_path() + if not xmlsec1: + raise Exception("Could not locate required 'xmlsec1' program") + cmd = [ xmlsec1, '--sign', '--privkey-pem', pems, '--output', cred_filename, unsigned_cred_filename] # print " ".join(cmd) -- 2.43.0