2 # GeniAPI authentication
10 from sfa.trust.credential import Credential
11 from sfa.trust.trustedroot import TrustedRootList
12 from sfa.trust.rights import RightList
13 from sfa.util.faults import *
14 from sfa.trust.hierarchy import Hierarchy
15 from sfa.util.genitable import GeniTable
16 from sfa.util.config import *
17 from sfa.util.misc import *
21 Credential based authentication
24 def __init__(self, peer_cert = None, config = None ):
25 self.peer_cert = peer_cert
26 self.hierarchy = Hierarchy()
27 self.trusted_cert_list = TrustedRootList().get_list()
29 self.config = Config()
32 def check(self, cred, operation):
34 Check the credential against the peer cert (callerGID included
35 in the credential matches the caller that is connected to the
36 HTTPS connection, check if the credential was signed by a
37 trusted cert and check if the credential is allowd to perform
38 the specified operation.
40 self.client_cred = Credential(string = cred)
41 self.client_gid = self.client_cred.get_gid_caller()
42 self.object_gid = self.client_cred.get_gid_object()
44 # make sure the client_gid is not blank
45 if not self.client_gid:
46 raise MissingCallerGID(self.client_cred.get_subject())
48 # make sure the client_gid matches client's certificate
49 peer_cert = self.peer_cert
50 if not peer_cert.is_pubkey(self.client_gid.get_pubkey()):
51 raise ConnectionKeyGIDMismatch(self.client_gid.get_subject())
53 # make sure the client is allowed to perform the operation
55 if not self.client_cred.can_perform(operation):
56 raise InsufficientRights(operation)
58 if self.trusted_cert_list:
59 self.client_cred.verify_chain(self.trusted_cert_list)
61 self.client_gid.verify_chain(self.trusted_cert_list)
63 self.object_gid.verify_chain(self.trusted_cert_list)
68 def get_auth_info(self, auth_hrn):
70 Given an authority name, return the information for that authority.
71 This is basically a stub that calls the hierarchy module.
73 @param auth_hrn human readable name of authority
76 return self.hierarchy.get_auth_info(auth_hrn)
79 def veriry_auth_belongs_to_me(self, name):
81 Verify that an authority belongs to our hierarchy.
82 This is basically left up to the implementation of the hierarchy
83 module. If the specified name does not belong, ane exception is
84 thrown indicating the caller should contact someone else.
86 @param auth_name human readable name of authority
89 self.get_auth_info(name)
92 def verify_object_belongs_to_me(self, name):
94 Verify that an object belongs to our hierarchy. By extension,
95 this implies that the authority that owns the object belongs
96 to our hierarchy. If it does not an exception is thrown.
98 @param name human readable name of object
100 auth_name = self.get_authority(name)
101 if not auth_name or name == self.config.SFA_INTERFACE_HRN:
102 # the root authority belongs to the registry by default?
103 # TODO: is this true?
105 self.verify_auth_belongs_to_me(auth_name)
107 def verify_auth_belongs_to_me(self, name):
108 # get auth info will throw an exception if the authority doesnt exist
109 self.get_auth_info(name)
112 def verify_object_permission(self, name):
114 Verify that the object gid that was specified in the credential
115 allows permission to the object 'name'. This is done by a simple
116 prefix test. For example, an object_gid for plc.arizona would
117 match the objects plc.arizona.slice1 and plc.arizona.
119 @param name human readable name to test
121 object_hrn = self.object_gid.get_hrn()
122 if object_hrn == name:
124 if name.startswith(object_hrn + "."):
126 if name.startswith(get_authority(name)):
129 raise PermissionError(name)
131 def determine_user_rights(self, src_cred, record):
133 Given a user credential and a record, determine what set of rights the
134 user should have to that record.
136 Src_cred can be None when obtaining a user credential, but should be
137 set to a valid user credential when obtaining a slice or authority
140 This is intended to replace determine_rights() and
141 verify_cancreate_credential()
144 type = record['type']
146 cred_object_hrn = src_cred.get_gid_object().get_hrn()
148 # supplying src_cred==None is only valid when obtaining user
150 #assert(type == "user")
152 cred_object_hrn = None
157 researchers = record.get("researcher", [])
158 if (cred_object_hrn in researchers):
165 elif type == "authority":
166 pis = record.get("pi", [])
167 operators = record.get("operator", [])
168 rl.add("authority,sa,ma")
169 if (cred_object_hrn in pis):
171 if (cred_object_hrn in operators):
181 def verify_cancreate_credential(self, src_cred, record):
183 Verify that a user can retrive a particular type of credential.
184 For slices, the user must be on the researcher list. For SA and
185 MA the user must be on the pi and operator lists respectively
188 type = record.get_type()
189 cred_object_hrn = src_cred.get_gid_object().get_hrn()
190 if cred_object_hrn in [self.config.SFA_REGISTRY_ROOT_AUTH]:
193 researchers = record.get("researcher", [])
194 if not (cred_object_hrn in researchers):
195 raise PermissionError(cred_object_hrn + " is not in researcher list for " + record.get_name())
197 pis = record.get("pi", [])
198 if not (cred_object_hrn in pis):
199 raise PermissionError(cred_object_hrn + " is not in pi list for " + record.get_name())
201 operators = record.get("operator", [])
202 if not (cred_object_hrn in operators):
203 raise PermissionError(cred_object_hrn + " is not in operator list for " + record.get_name())
205 def get_authority(self, hrn):
206 return get_authority(hrn)