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 get_auth_table(self, auth_name):
81 Given an authority name, return the database table for that authority.
82 If the databse table does not exist, then one will be automatically
85 @param auth_name human readable name of authority
87 auth_info = self.get_auth_info(auth_name)
88 table = GeniTable(hrn=auth_name,
89 cninfo=auth_info.get_dbinfo())
90 # if the table doesn't exist, then it means we haven't put any records
91 # into this authority yet.
93 if not table.exists():
94 print >> log, "Registry: creating table for authority", auth_name
99 def veriry_auth_belongs_to_me(self, name):
101 Verify that an authority belongs to our hierarchy.
102 This is basically left up to the implementation of the hierarchy
103 module. If the specified name does not belong, ane exception is
104 thrown indicating the caller should contact someone else.
106 @param auth_name human readable name of authority
109 self.get_auth_info(name)
112 def verify_object_belongs_to_me(self, name):
114 Verify that an object belongs to our hierarchy. By extension,
115 this implies that the authority that owns the object belongs
116 to our hierarchy. If it does not an exception is thrown.
118 @param name human readable name of object
120 auth_name = self.get_authority(name)
122 # the root authority belongs to the registry by default?
123 # TODO: is this true?
125 self.verify_auth_belongs_to_me(auth_name)
127 def verify_auth_belongs_to_me(self, name):
128 # get auth info will throw an exception if the authority doesnt exist
129 self.get_auth_info(name)
132 def verify_object_permission(self, name):
134 Verify that the object gid that was specified in the credential
135 allows permission to the object 'name'. This is done by a simple
136 prefix test. For example, an object_gid for plc.arizona would
137 match the objects plc.arizona.slice1 and plc.arizona.
139 @param name human readable name to test
141 object_hrn = self.object_gid.get_hrn()
142 if object_hrn == name:
144 if name.startswith(object_hrn + "."):
146 if name.startswith(get_authority(name)):
149 raise PermissionError(name)
151 def determine_user_rights(self, src_cred, record):
153 Given a user credential and a record, determine what set of rights the
154 user should have to that record.
156 Src_cred can be None when obtaining a user credential, but should be
157 set to a valid user credential when obtaining a slice or authority
160 This is intended to replace determine_rights() and
161 verify_cancreate_credential()
164 type = record.get_type()
166 cred_object_hrn = src_cred.get_gid_object().get_hrn()
168 # supplying src_cred==None is only valid when obtaining user
170 #assert(type == "user")
172 cred_object_hrn = None
177 researchers = record.get("researcher", [])
178 if (cred_object_hrn in researchers):
185 elif type == "authority":
186 pis = record.get("pi", [])
187 operators = record.get("operator", [])
188 rl.add("authority,sa,ma")
189 if (cred_object_hrn in pis):
191 if (cred_object_hrn in operators):
201 def verify_cancreate_credential(self, src_cred, record):
203 Verify that a user can retrive a particular type of credential.
204 For slices, the user must be on the researcher list. For SA and
205 MA the user must be on the pi and operator lists respectively
208 type = record.get_type()
209 cred_object_hrn = src_cred.get_gid_object().get_hrn()
210 if cred_object_hrn in [self.config.SFA_REGISTRY_ROOT_AUTH]:
213 researchers = record.get("researcher", [])
214 if not (cred_object_hrn in researchers):
215 raise PermissionError(cred_object_hrn + " is not in researcher list for " + record.get_name())
217 pis = record.get("pi", [])
218 if not (cred_object_hrn in pis):
219 raise PermissionError(cred_object_hrn + " is not in pi list for " + record.get_name())
221 operators = record.get("operator", [])
222 if not (cred_object_hrn in operators):
223 raise PermissionError(cred_object_hrn + " is not in operator list for " + record.get_name())
225 def get_authority(self, hrn):
226 return get_authority(hrn)