X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fclient%2Fsfaclientlib.py;h=f4fe3a8d7fe4bc0e93f79f9cb2d73268b954c950;hb=0f4b3c7754fe622c6ad7b4f3b418ea648967f21c;hp=c5c5b8021c42c4259b493b6fc08020f3d5799e68;hpb=97d09a321eff49c73c09f44a10d1ae0d7767d250;p=sfa.git diff --git a/sfa/client/sfaclientlib.py b/sfa/client/sfaclientlib.py index c5c5b802..f4fe3a8d 100644 --- a/sfa/client/sfaclientlib.py +++ b/sfa/client/sfaclientlib.py @@ -9,6 +9,7 @@ import sys import os,os.path +import subprocess from datetime import datetime from sfa.util.xrn import Xrn @@ -22,8 +23,9 @@ from sfa.client.sfaserverproxy import SfaServerProxy # see optimizing dependencies below from sfa.trust.certificate import Keypair, Certificate from sfa.trust.credential import Credential +from sfa.trust.gid import GID ########## -# a helper class to implement the bootstrapping of crypto. material +# a helper class to implement the bootstrapping of cryptoa. material # assuming we are starting from scratch on the client side # what's needed to complete a full slice creation cycle # (**) prerequisites: @@ -51,7 +53,11 @@ from sfa.trust.credential import Credential # obtained at the registry with Resolve # using the (step2) user-credential as credential # default filename is ..cred - +# +# (**) additionnally, it might make sense to upgrade a GID file +# into a pkcs12 certificate usable in a browser +# this bundled format allows for embedding the private key +# ########## Implementation notes # @@ -82,11 +88,16 @@ from sfa.trust.credential import Credential # the usage model is to reuse an existing keypair) # # there might be a more portable, i.e. less language-dependant way, to -# implement this step by exec'ing the openssl command a known -# successful attempt at this approach that worked for Java is -# documented below +# implement this step by exec'ing the openssl command. +# a known successful attempt at this approach that worked +# for Java is documented below # http://nam.ece.upatras.gr/fstoolkit/trac/wiki/JavaSFAClient # +# (*) pkcs12 +# +# the implementation of the pkcs12 wrapping, which is a late addition, +# is done through direct calls to openssl +# #################### class SfaClientException (Exception): pass @@ -193,12 +204,28 @@ class SfaClientBootstrap: return output +# http://trac.myslice.info/wiki/MySlice/Developer/SFALogin +### produce a pkcs12 bundled certificate from GID and private key +# xxx for now we put a hard-wired password that's just, well, 'password' +# when leaving this empty on the mac, result can't seem to be loaded in keychain.. + def my_pkcs12_produce (self, filename): + password=raw_input("Enter password for p12 certificate: ") + openssl_command=['openssl', 'pkcs12', "-export"] + openssl_command += [ "-password", "pass:%s"%password ] + openssl_command += [ "-inkey", self.private_key_filename()] + openssl_command += [ "-in", self.my_gid_filename()] + openssl_command += [ "-out", filename ] + if subprocess.call(openssl_command) ==0: + print "Successfully created %s"%filename + else: + print "Failed to create %s"%filename + # Returns True if credential file is valid. Otherwise return false. def validate_credential(self, filename): valid = True cred = Credential(filename=filename) # check if credential is expires - if cred.get_expiration() < datetime.now(): + if cred.get_expiration() < datetime.utcnow(): valid = False return valid @@ -259,7 +286,8 @@ class SfaClientBootstrap: return self.gid_filename (self.hrn, "user") def gid_filename (self, hrn, type): return self.fullpath ("%s.%s.gid"%(hrn,type)) - + def my_pkcs12_filename (self): + return self.fullpath ("%s.p12"%self.hrn) # optimizing dependencies # originally we used classes GID or Credential or Certificate @@ -326,6 +354,9 @@ class SfaClientBootstrap: @get_or_produce (my_gid_filename, my_gid_produce) def my_gid (self): pass + @get_or_produce (my_pkcs12_filename, my_pkcs12_produce) + def my_pkcs12 (self): pass + @get_or_produce (credential_filename, credential_produce, validate_credential) def credential (self, hrn, type): pass @@ -354,3 +385,38 @@ class SfaClientBootstrap: def private_key (self): self.assert_private_key() return self.private_key_filename() + + def delegate_credential_string (self, original_credential, to_hrn, to_type='authority'): + """ + sign a delegation credential to someone else + + original_credential : typically one's user- or slice- credential to be delegated to s/b else + to_hrn : the hrn of the person that will be allowed to do stuff on our behalf + to_type : goes with to_hrn, usually 'user' or 'authority' + + returns a string with the delegated credential + + this internally uses self.my_gid() + it also retrieves the gid for to_hrn/to_type + and uses Credential.delegate()""" + + # the gid and hrn of the object we are delegating + if isinstance (original_credential, str): + original_credential = Credential (string=original_credential) + original_gid = original_credential.get_gid_object() + original_hrn = original_gid.get_hrn() + + if not original_credential.get_privileges().get_all_delegate(): + self.logger.error("delegate_credential_string: original credential %s does not have delegate bit set"%original_hrn) + return + + # the delegating user's gid + my_gid = self.my_gid() + + # retrieve the GID for the entity that we're delegating to + to_gidfile = self.gid (to_hrn,to_type) +# to_gid = GID ( to_gidfile ) +# to_hrn = delegee_gid.get_hrn() +# print 'to_hrn',to_hrn + delegated_credential = original_credential.delegate(to_gidfile, self.private_key(), my_gid) + return delegated_credential.save_to_string(save_parents=True)