X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=sfa%2Fclient%2Fsfaclientlib.py;h=2b5cb1992e3e6436e3ea66f5debe0136c639489b;hb=935de64c2ed3a68566da471c68447a1ac384455d;hp=25d2ce49c48ed87acebef33700a2f95a7b654ae4;hpb=f851dd7b8c1e786e03c96e0eb3fa73e5e3825f20;p=sfa.git diff --git a/sfa/client/sfaclientlib.py b/sfa/client/sfaclientlib.py index 25d2ce49..2b5cb199 100644 --- a/sfa/client/sfaclientlib.py +++ b/sfa/client/sfaclientlib.py @@ -1,3 +1,4 @@ +# Thierry Parmentelat -- INRIA # # a minimal library for writing "lightweight" SFA clients # @@ -6,33 +7,10 @@ import os,os.path import sfa.util.sfalogging -from sfa.trust.gid import GID +from sfa.client.sfaserverproxy import SfaServerProxy + +# see optimizing dependencies below from sfa.trust.certificate import Keypair, Certificate -from sfa.trust.credential import Credential - -import sfa.client.sfaprotocol as sfaprotocol - -class SfaServerProxy: - - def __init__ (self, url, keyfile, certfile, verbose=False, timeout=None): - self.url=url - self.keyfile=keyfile - self.certfile=certfile - self.verbose=verbose - self.timeout=timeout - # an instance of xmlrpclib.ServerProxy - self.serverproxy=sfaprotocol.server_proxy \ - (self.url, self.keyfile, self.certfile, self.timeout, self.verbose) - - # this is python magic to return the code to run when - # SfaServerProxy receives a method call - # so essentially we send the same method with identical arguments - # to the server_proxy object - def __getattr__(self, name): - def func(*args, **kwds): - return getattr(self.serverproxy, name)(*args, **kwds) - return func - ########## # a helper class to implement the bootstrapping of crypto. material @@ -70,44 +48,77 @@ class SfaClientBootstrap: print 'special case for logger' logger = sfa.util.sfalogging.logger self.logger=logger - + + #################### public interface + + # xxx should that be called in the constructor ? + # typically user_private_key is ~/.ssh/id_rsa + def init_private_key_if_missing (self, user_private_key): + private_key_filename=self.private_key_filename() + if not os.path.isfile (private_key_filename): + key=self.plain_read(user_private_key) + self.plain_write(private_key_filename, key) + os.chmod(private_key_filename,os.stat(user_private_key).st_mode) + self.logger.debug("SfaClientBootstrap: Copied private key from %s into %s"%\ + (user_private_key,private_key_filename)) + + # make sure we have the GID at hand + def bootstrap_gid (self): + if self.any_certificate_filename() is None: + self.get_self_signed_cert() + self.get_credential() + self.get_gid() + + def server_proxy (self, url): + return SfaServerProxy (url, self.private_key_filename(), self.gid_filename()) + + def get_credential_string (self): + return self.plain_read (self.get_credential()) + + # more to come to get credentials about other objects (authority/slice) + + #################### private details # stupid stuff def fullpath (self, file): return os.path.join (self.dir,file) # %s -> self.hrn def fullpath_format(self,format): return self.fullpath (format%self.hrn) - def private_key_file (self): + def private_key_filename (self): return self.fullpath_format ("%s.pkey") - - def self_signed_cert_file (self): + def self_signed_cert_filename (self): return self.fullpath_format ("%s.sscert") - def credential_file (self): + def credential_filename (self): return self.fullpath_format ("%s.user.cred") - def gid_file (self): + def gid_filename (self): return self.fullpath_format ("%s.user.gid") +# optimizing dependencies +# originally we used classes GID or Credential or Certificate +# like e.g. +# return Credential(filename=self.get_credential()).save_to_string() +# but in order to make it simpler to other implementations/languages.. + def plain_read (self, filename): + infile=file(filename,"r") + result=infile.read() + infile.close() + return result + + def plain_write (self, filename, contents): + outfile=file(filename,"w") + result=outfile.write(contents) + outfile.close() + + # the private key def check_private_key (self): - if not os.path.isfile (self.private_key_file()): - raise Exception,"No such file %s"%self.private_key_file() + if not os.path.isfile (self.private_key_filename()): + raise Exception,"No such file %s"%self.private_key_filename() return True - # typically user_private_key is ~/.ssh/id_rsa - def init_private_key_if_missing (self, user_private_key): - private_key_file=self.private_key_file() - if not os.path.isfile (private_key_file): - infile=file(user_private_key) - outfile=file(private_key_file,'w') - outfile.write(infile.read()) - outfile.close() - infile.close() - os.chmod(private_key_file,os.stat(user_private_key).st_mode) - self.logger.debug("SfaClientBootstrap: Copied private key from %s into %s"%\ - (user_private_key,private_key_file)) - - - # get any certificate, gid preferred - def preferred_certificate_file (self): - attempts=[ self.gid_file(), self.self_signed_cert_file() ] + # get any certificate + # rationale for this method, once we have the gid, it's actually safe + # to remove the .sscert + def any_certificate_filename (self): + attempts=[ self.gid_filename(), self.self_signed_cert_filename() ] for attempt in attempts: if os.path.isfile (attempt): return attempt return None @@ -116,8 +127,8 @@ class SfaClientBootstrap: # unconditionnally def create_self_signed_certificate (self,output): self.check_private_key() - private_key_file = self.private_key_file() - keypair=Keypair(filename=private_key_file) + private_key_filename = self.private_key_filename() + keypair=Keypair(filename=private_key_filename) self_signed = Certificate (subject = self.hrn) self_signed.set_pubkey (keypair) self_signed.set_issuer (keypair, self.hrn) @@ -128,67 +139,51 @@ class SfaClientBootstrap: return output def get_self_signed_cert (self): - self_signed_cert_file = self.self_signed_cert_file() - if os.path.isfile (self_signed_cert_file): - return self_signed_cert_file - return self.create_self_signed_certificate(self_signed_cert_file) + self_signed_cert_filename = self.self_signed_cert_filename() + if os.path.isfile (self_signed_cert_filename): + return self_signed_cert_filename + return self.create_self_signed_certificate(self_signed_cert_filename) ### step2 # unconditionnally def retrieve_credential (self, output): self.check_private_key() - certificate_file = self.preferred_certificate_file() - registry_proxy = SfaServerProxy (self.registry_url, self.private_key_file(), - certificate_file) - certificate = Certificate (filename=certificate_file) - certificate_string = certificate.save_to_string(save_parents=True) + certificate_filename = self.any_certificate_filename() + certificate_string = self.plain_read (certificate_filename) + registry_proxy = SfaServerProxy (self.registry_url, self.private_key_filename(), + certificate_filename) credential_string=registry_proxy.GetSelfCredential (certificate_string, self.hrn, "user") - credential = Credential (string=credential_string) - credential.save_to_file (output, save_parents=True) + self.plain_write (output, credential_string) self.logger.debug("SfaClientBootstrap: Wrote result of GetSelfCredential in %s"%output) return output def get_credential (self): - credential_file = self.credential_file () - if os.path.isfile(credential_file): - return credential_file - return self.retrieve_credential (credential_file) - - def get_credential_string (self): - return Credential(filename=self.get_credential()).save_to_string() + credential_filename = self.credential_filename () + if os.path.isfile(credential_filename): + return credential_filename + return self.retrieve_credential (credential_filename) ### step3 # unconditionnally def retrieve_gid (self, hrn, type, output): self.check_private_key() - certificate_file = self.preferred_certificate_file() - registry_proxy = SfaServerProxy (self.registry_url, self.private_key_file(), - certificate_file) - credential_string=Credential(filename=self.credential_file()).save_to_string() + certificate_filename = self.any_certificate_filename() + registry_proxy = SfaServerProxy (self.registry_url, self.private_key_filename(), + certificate_filename) + credential_string=self.plain_read (self.get_credential()) records = registry_proxy.Resolve (hrn, credential_string) records=[record for record in records if record['type']==type] if not records: # RecordNotFound raise Exception, "hrn %s (%s) unknown to registry %s"%(hrn,type,self.registry_url) record=records[0] - gid=GID(string=record['gid']) - gid.save_to_file (filename=output) + self.plain_write (output, record['gid']) self.logger.debug("SfaClientBootstrap: Wrote GID for %s (%s) in %s"% (hrn,type,output)) return output def get_gid (self): - gid_file=self.gid_file() - if os.path.isfile(gid_file): - return gid_file - return self.retrieve_gid(self.hrn, "user", gid_file) - - # make sure we have the GID at hand - def bootstrap_gid (self): - if self.preferred_certificate_file() is None: - self.get_self_signed_cert() - self.get_credential() - self.get_gid() - - def server_proxy (self, url): - return SfaServerProxy (url, self.private_key_file(), self.gid_file()) + gid_filename=self.gid_filename() + if os.path.isfile(gid_filename): + return gid_filename + return self.retrieve_gid(self.hrn, "user", gid_filename)