Changeset 5c0d244 for fedd/federation
- Timestamp:
- Sep 13, 2010 9:51:13 AM (14 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master
- Children:
- 9cce15a
- Parents:
- 49e66b4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/federation/authorizer.py
r49e66b4 r5c0d244 1 1 #/usr/local/bin/python 2 2 3 from tempfile import mkstemp 4 from subprocess import call 3 5 from fedid import fedid 4 6 from remote_service import service_caller … … 6 8 from service_error import service_error 7 9 10 import ABAC 11 import pickle 12 8 13 import sys 14 import os 9 15 10 16 class authorizer_base: … … 17 23 # general error exception for badly formed names. 18 24 class bad_name(RuntimeError): pass 25 # difficulty creating an attribute 26 class attribute_error(RuntimeError): pass 19 27 20 28 @staticmethod … … 146 154 return rv 147 155 156 def clone(self): 157 rv = authorizer() 158 rv.attrs = self.attrs.copy() 159 rv.globals = self.globals.copy() 160 return rv 161 162 def save(self, fn): 163 f = open(fn, "w") 164 pickle.dump(self, f) 165 f.close() 166 167 def load(self, fn): 168 f = open(fn, "r") 169 a = pickle.load(f) 170 f.close() 171 self.attrs = a.attrs 172 self.globals = a.globals 173 174 148 175 class abac_authorizer(authorizer_base): 149 176 """ … … 151 178 """ 152 179 153 def __init__(self, url=None, cert_file=None, cert_pwd=None, 154 trusted_certs=None, me=None): 155 self.call_CreateContext = abac_service_caller('CreateContext') 156 self.call_CredentialUpdate = abac_service_caller('CredentialUpdate') 157 self.call_Access = abac_service_caller('Access') 180 def __init__(self, certs=None, me=None, key=None, from_dir=None): 181 self.bad_name = authorizer_base.bad_name 182 self.attribute_error = authorizer_base.attribute_error 158 183 self.globals = set() 159 160 self.url = url 161 self.cert_file = cert_file 162 self.cert_pwd = cert_pwd 163 self.trusted_certs = trusted_certs 184 self.creddy = '/usr/local/bin/creddy' 164 185 self.me = me 165 req = { 'context': { 'self': me.get_hexstr()} } 166 # May throw a service error 167 resp = self.call_CreateContext(self.url, req, self.cert_file, 168 self.cert_pwd, self.trusted_certs, tracefile=sys.stderr) 169 170 if resp.has_key('CreateContextResponseBody'): 171 resp = resp['CreateContextResponseBody'] 172 if resp.has_key('contextID'): 173 self.contextID = resp['contextID'] 186 self.my_key = key 187 self.context = ABAC.Context() 188 for dir in certs or []: 189 self.context.load_directory(dir) 190 191 def set_attribute(self, name=None, attr=None, cert=None): 192 if name and attr: 193 if isinstance(name, tuple): 194 raise self.bad_name("ABAC doesn't understand three-names") 195 if self.me and self.key: 196 # Create a credential and insert it into context 197 # This will simplify when we have libcreddy 198 try: 199 # create temp file 200 f, fn = mkstemp() 201 f.close() 202 except EnvironmentError, e: 203 raise self.attribute_error( 204 "Cannot create temp file: %s" %e) 205 206 # Create the attribute certificate with creddy 207 rv = call([creddy, '--attribute', '--issuer=%s' % self.me, 208 '--key=%s' % self.key, '--role=%s' % attr, 209 '--subject-id=%s' % name, '--out=%s' % fn]) 210 if rv == 0: 211 # load it to context and remove the file 212 self.context.load_attribute(fn) 213 os.unlink(fn) 214 else: 215 os.unlink(fn) 216 raise self.attribute_error("creddy returned %s" % rv) 174 217 else: 175 raise service_error(service_error.internal, 176 "No context ID for the new authorization context") 177 else: 178 raise service_error(service_error.internal, 179 "Bad response to creating service context") 180 181 def set_attribute(self, name, attr): 182 self.valid_name(name) 218 raise self.attribute_error( 219 "Identity and key not specified on creation") 220 elif cert: 221 # Insert this credential into the context 222 self.context.load_attribute_chunk(cert) 223 else: 224 raise self.attribute_error("Neither name/attr nor cert is set") 225 226 def check_attribute(self, name, attr): 227 # XXX proof soon 183 228 if isinstance(name, tuple): 184 if not isinstance(name[0], fedid): 185 raise service_error(service_error.internal, 186 "Triple not anchored in testbed") 187 if not name[1] and not name[2]: 188 raise service_error(service_error.internal, 189 "Anonymous access not yet permitted") 190 191 preconditions = "^".join( 192 [ "%s.%s" % (name[0], self.auth_name(n)) \ 193 for n in name[1:3] if n ]) 194 195 req = { 196 'credential': [ '%s.%s<--%s' % \ 197 ( self.me, attr, preconditions) ], 198 'context': { 'contextID': self.contextID } 199 } 200 else: 201 req = { 202 'credential': [ '%s.%s<--%s' % \ 203 ( self.me, attr, self.auth_name(name)) ], 204 'context': { 'contextID': self.contextID } 205 } 206 print req 207 self.call_CredentialUpdate(self.url, req, self.cert_file, 208 self.cert_pwd, self.trusted_certs, tracefile=sys.stderr) 209 210 def check_attribute(self, name, attr): 211 self.valid_name(name) 212 if attr in self.globals: return True 213 214 if isinstance(name, tuple): 215 raise service_error(service_error.internal, 216 "Only fedids permitted here") 217 req = { 218 'goal': '%s:%s<<---%s' % (self.me, attr, name), 219 'context': { 'contextID': self.contextID } 220 } 221 resp = self.call_Access(self.url, req, self.cert_file, self.cert_pwd, 222 self.trusted_certs) 223 if resp.has_key('AccessResponseBody'): 224 resp = resp['AccessResponseBody'] 225 226 result = resp.get('result', None) 227 return (result and result.lower() == 'true') 229 raise self.bad_name("ABAC doesn't understand three-names") 230 else: 231 proof, rv = self.context.query(attr, name) 232 # XXX delete soon 233 if not rv and attr in self.globals: return True 234 else: return rv 228 235 229 236 def set_global_attribute(self, attr): … … 241 248 self.globals.discard(attr) 242 249 250 def clone(self): 251 rv = abac_authorizer(me=self.me, key=self.key) 252 rv.globals = self.globals.copy() 253 rv.context = ABAC.Context(self.context) 254 return rv 255 256 def save(self, dir): 257 os.mkdir(dir) 258 259 f = open("%s/globals" % dir, "w") 260 pickle.dump(self.globals, f) 261 f.close() 262 263 if self.me and self.key: 264 f = open("%s/me" % dir, "w") 265 pickle.dump(self.me, f) 266 f.close() 267 f = open("%s/key" % dir, "w") 268 pickle.dump(self.key, f) 269 f.close() 270 os.mkdir("%s/certs" % dir) 271 seenit = set() 272 ii = 0 273 ai = 0 274 for c in self.context.credentials(): 275 id = c.issuer_cert() 276 attr = c.attribute_cert() 277 if id not in seenit: 278 f = open("%s/certs/%03d_ID.der" % (dir, ii), "w") 279 print >>f, id 280 f.close() 281 ii += 1 282 seenit.add(id) 283 if attr: 284 f = open("%s/certs/%03d_attr.der" % (dir, ai), "w") 285 print >>f, attr 286 f.close() 287 ai += 1 288 289 def load(self, dir): 290 if os.access("%s/me" % dir, os.R_OK): 291 f = open("%s/me" % dir, "r") 292 self.me = pickle.load(f) 293 f.close() 294 else: 295 self.me = None 296 if os.access("%s/key" % dir, os.R_OK): 297 f = open("%s/key" % dir, "r") 298 self.key = pickle.load(f) 299 f.close() 300 else: 301 self.key = None 302 f = open("%s/globals" % dir, "r") 303 self.globals = pickle.load(f) 304 f.close() 305 self.context = ABAC.context() 306 self.context.load_directory("%s/certs" % dir) 307
Note: See TracChangeset
for help on using the changeset viewer.