- Timestamp:
- Jan 15, 2011 5:52:15 PM (14 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master
- Children:
- aaf7f41
- Parents:
- ac15159 (diff), 944b746 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Ted Faber <faber@…> (01/15/11 17:51:40)
- git-committer:
- Ted Faber <faber@…> (01/15/11 17:52:15)
- Location:
- fedd
- Files:
-
- 2 added
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/Makefile
rac15159 r0a49bd7 4 4 GENERATED_MODS= ${MODULE_DIR}/fedd_services.py \ 5 5 ${MODULE_DIR}/fedd_internal_services.py \ 6 ${MODULE_DIR}/fedd_services_types.py 6 ${MODULE_DIR}/fedd_internal_services_types.py \ 7 ${MODULE_DIR}/fedd_client.py \ 8 ${MODULE_DIR}/fedd_internal_client.py \ 9 ${MODULE_DIR}/fedd_internal_server.py \ 10 ${MODULE_DIR}/fedd_internal_types.py \ 11 ${MODULE_DIR}/fedd_types.py \ 12 ${MODULE_DIR}/fedd_server.py 13 7 14 WSDL_FILES= ../wsdl/fedd.wsdl ../wsdl/fedd_types.xsd ../wsdl/fedd_internal.wsdl ../wsdl/topdl.xsd 8 15 9 VERSION=3. 0116 VERSION=3.20 10 17 11 18 DISTFILES= dist/fedd-${VERSION}.tar.gz … … 15 22 16 23 ${GENERATED_MODS}: ${WSDL_FILES} 17 wsdl2py --complexType --output-dir=${MODULE_DIR} ../wsdl/fedd.wsdl18 wsdl2py --complexType --output-dir=${MODULE_DIR} ../wsdl/fedd_internal.wsdl24 python ./compile_wsdl.py --complexType --output-dir=${MODULE_DIR} ../wsdl/fedd.wsdl 25 python ./compile_wsdl.py --complexType --output-dir=${MODULE_DIR} ../wsdl/fedd_internal.wsdl 19 26 20 27 clean: -
fedd/access_to_abac.py
rac15159 r0a49bd7 12 12 from federation.fedid import fedid 13 13 from federation.authorizer import abac_authorizer 14 from federation.util import abac_split_cert, abac_pem_type 14 from federation.util import abac_split_cert, abac_pem_type, file_expanding_opts 15 15 16 16 … … 185 185 186 186 187 def parse_access(fn, mapper ):187 def parse_access(fn, mapper, delegation_link): 188 188 """ 189 189 Parse the access file, calling out to the mapper to parse specific … … 224 224 225 225 226 class access_opts( OptionParser):226 class access_opts(file_expanding_opts): 227 227 ''' 228 228 Parse the options for this program. Most are straightforward, but the … … 247 247 248 248 def __init__(self): 249 OptionParser.__init__(self, usage='%prog [opts] file [...]')249 file_expanding_opts.__init__(self, usage='%prog [opts] file [...]') 250 250 self.add_option('--cert', dest='cert', default=None, 251 type='str', action='callback', callback=self.expand_file, 251 252 help='my fedid as an X.509 certificate') 252 253 self.add_option('--key', dest='key', default=None, 254 type='str', action='callback', callback=self.expand_file, 253 255 help='key for the certificate') 254 256 self.add_option('--dir', dest='dir', default=None, 257 type='str', action='callback', callback=self.expand_file, 255 258 help='Output directory for credentials') 256 259 self.add_option('--type', action='callback', nargs=1, type='str', … … 263 266 default=False, 264 267 help='Do not print credential to local attribute map') 265 self.add_option('--create-creds', action='store_true', 266 dest='create_creds', default=False, 267 help='create credentials for rules. Requires ' + \ 268 '--cert, --key, and --dir to be given.') 268 self.add_option('--no_create_creds', action='store_false', 269 dest='create_creds', default=True, 270 help='Do not create credentials for rules.') 269 271 self.add_option('--file', dest='file', default=None, 272 type='str', action='callback', callback=self.expand_file, 270 273 help='Access DB to parse. If this is present, ' + \ 271 274 'omit the positional filename') 272 275 self.add_option('--mapfile', dest='map', default=None, 276 type='str', action='callback', callback=self.expand_file, 273 277 help='File for the attribute to local authorization data') 274 278 self.add_option('--no-delegate', action='store_false', dest='delegate', … … 276 280 help='do not accept delegated attributes with the ' +\ 277 281 'acting_for linking role') 278 self.add_option('-- auth', action='store_true', dest='create_auth',279 default= False, help='create a full ABAC authorizer')282 self.add_option('--no_auth', action='store_false', dest='create_auth', 283 default=True, help='do not create a full ABAC authorizer') 280 284 self.add_option('--debug', action='store_true', dest='debug', 281 285 default=False, help='Just print actions') … … 402 406 for fn in args: 403 407 try: 404 creds, to_id = parse_access(fn, opts.mapper )408 creds, to_id = parse_access(fn, opts.mapper, delegation_link) 405 409 except parse_error, e: 406 410 print >> sys.stderr, "%s" % e -
fedd/cert_to_fedid.py
rac15159 r0a49bd7 3 3 import sys, os 4 4 import subprocess, tempfile 5 import os.path 6 import re 7 8 from M2Crypto import X509 5 9 6 10 from string import join 7 from optparse import OptionParser 8 from federation.util import abac_pem_type, abac_split_cert 11 from federation.util import abac_pem_type, abac_split_cert, file_expanding_opts 9 12 10 class Parser( OptionParser):13 class Parser(file_expanding_opts): 11 14 def __init__(self): 12 OptionParser.__init__(self, usage='%prog [options]')15 file_expanding_opts.__init__(self, usage='%prog [options]') 13 16 self.add_option('--out', dest='out', help='destination file', 17 action='callback', callback=self.expand_file, type='str', 14 18 default='./cert.pem') 15 19 self.add_option('--debug', dest='debug', action='store_true', 16 20 default=False, help='Just print command') 21 self.add_option('--cert', dest='cert', 22 help='Cretificate to copy subject from') 17 23 self.add_option('--openssl', dest='openssl', 18 24 help='Path to openssl command', default='/usr/bin/openssl') … … 31 37 delete_key = True 32 38 elif ktype != 'key': 33 sys.exit('Cannot use %s as identity. It is a %s ' % ktype+39 sys.exit('Cannot use %s as identity. It is a %s ' % (key, ktype) + 34 40 'and we were expecting a key') 35 41 36 42 37 43 try: 44 c = X509.load_cert(opts.cert) 45 subj = c.get_subject().as_text() 46 if subj.startswith('/'): i = 1 47 else: i = 0 48 subj = '/' + re.sub('/', '\/', subj[i:]) 49 38 50 tf, tn = tempfile.mkstemp(suffix=".pem") 39 51 cmd = [opts.openssl, 'req', '-new', '-nodes', '-subj', 40 '/CN=users.isi.deterlab.net', '-x509', '-days', '3650',52 subj, '-x509', '-days', '3650', 41 53 '-key', key, '-out', tn] 42 54 if opts.debug: -
fedd/confirm_sshkey.py
rac15159 r0a49bd7 3 3 import os, sys 4 4 import MySQLdb 5 from optparse import OptionParser5 from federation.util import file_expanding_opts 6 6 7 7 8 class opt_parser( OptionParser):8 class opt_parser(file_expanding_opts): 9 9 def __init__(self): 10 10 OptionParser.__init__(self, usage="%prog [opts] (--help for details)", … … 12 12 self.add_option('-u', '--user', dest='user', action='store', 13 13 default=None, help="User to confirm key of") 14 self.add_option('-f', '--keyfile', dest='keyfile', action='store', 14 self.add_option('-f', '--keyfile', dest='keyfile', 15 action='callback', callback=self.expand_file, type='str', 15 16 default=None, help="file containing pubkey to confirm") 16 self.add_option('-k', '--key', dest='key', 17 default=None, action='store',17 self.add_option('-k', '--key', dest='key', default=None, 18 action='callback', callback=self.expand_file, type='str', 18 19 help='Key on the command line') 19 20 self.add_option('-q', '--quiet', dest='verbose', action='store_false', -
fedd/creddy_split.py
rac15159 r0a49bd7 5 5 import os 6 6 7 from optparse import OptionParser 8 from federation.util import abac_split_cert, abac_pem_type 7 from federation.util import abac_split_cert, abac_pem_type, file_expanding_opts 9 8 10 9 # Options 11 class Parser( OptionParser):10 class Parser(file_expanding_opts): 12 11 def __init__(self): 13 OptionParser.__init__(self, usage="%prog [options] file.pem")12 file_expanding_opts.__init__(self, usage="%prog [options] file.pem") 14 13 self.add_option('--cert', dest='cert', default='./cert.pem', 14 action='callback', callback=self.expand_file, type='str', 15 15 help='File to extract certificate into, default: [%default]') 16 16 self.add_option('--key', dest='key', default='./key.pem', 17 action='callback', callback=self.expand_file, type='str', 17 18 help='File to extract key into, default: [%default]') 18 19 self.add_option('--force', action='store_true', dest='force', -
fedd/fedd.py
rac15159 r0a49bd7 7 7 from federation import config_parser 8 8 from federation.server import server, xmlrpc_handler, soap_handler 9 from federation.util import fedd_ssl_context 9 from federation.util import fedd_ssl_context, file_expanding_opts 10 10 from federation.deter_impl import new_feddservice 11 11 … … 18 18 import logging 19 19 import M2Crypto 20 21 class fedd_opts(OptionParser): 20 import os.path 21 22 class fedd_opts(file_expanding_opts): 22 23 """Encapsulate option processing in this class, rather than in main""" 24 23 25 def __init__(self): 24 OptionParser.__init__(self, usage="%prog [opts] (--help for details)", 26 file_expanding_opts.__init__(self, 27 usage="%prog [opts] (--help for details)", 25 28 version="0.1") 26 29 … … 29 32 self.add_option("-d", "--debug", action="count", dest="debug", 30 33 help="Set debug. Repeat for more information") 31 self.add_option("-f", "--configfile", action="store", 34 self.add_option("-f", "--configfile", action="callback", 35 callback=self.expand_file, type='str', 32 36 default="/usr/local/etc/fedd.conf", 33 dest="configfile", help="Configuration file (required)")37 dest="configfile", help="Configuration file") 34 38 self.add_option("-l", "--logfile", action="store", dest="logfile", 35 39 help="File to send log messages to") -
fedd/fedd_create.py
rac15159 r0a49bd7 7 7 import ABAC 8 8 9 from string import join 10 9 from string import join, ascii_letters 10 from random import choice 11 12 from federation.proof import proof 11 13 from federation.fedid import fedid, generate_fedid 12 14 from federation.remote_service import service_caller 13 15 from federation.client_lib import client_opts, exit_with_fault, RPCException, \ 14 16 wrangle_standard_options, do_rpc, get_experiment_names, save_certfile,\ 15 get_abac_certs 17 get_abac_certs, log_authentication 16 18 from federation.util import abac_split_cert, abac_context_to_creds 17 19 from federation import topdl … … 26 28 client_opts.__init__(self) 27 29 self.add_option("--experiment_cert", dest="out_certfile", 30 action="callback", callback=self.expand_file, 28 31 type="string", help="output certificate file") 29 32 self.add_option("--experiment_name", dest="exp_name", 30 33 type="string", help="Suggested experiment name") 31 self.add_option("--file", dest="file", 34 self.add_option("--file", dest="file", action="callback", 35 callback=self.expand_file, type="str", 32 36 help="experiment description file") 33 37 self.add_option("--project", action="store", dest="project", … … 153 157 (opts, args) = parser.parse_args() 154 158 159 svcs = [] 155 160 # Option processing 156 cert, fid, url = wrangle_standard_options(opts) 161 try: 162 cert, fid, url = wrangle_standard_options(opts) 163 except RuntimeError, e: 164 sys.exit("%s" %e) 157 165 158 166 if opts.file: … … 199 207 200 208 # Fill in services 201 svcs = []202 209 if opts.master and opts.project: 203 210 svcs.append(project_export_service(opts.master, opts.project)) … … 231 238 if acerts: 232 239 msg['credential'] = acerts 240 241 # ZSI will not properly construct an empty message. If nothing has been added 242 # to msg, pick a random localname to ensure the message is created 243 if not msg: 244 msg['experimentID'] = { 245 'localname': join([choice(ascii_letters) for i in range(0,8)],""), 246 } 247 233 248 234 249 if opts.debug > 1: print >>sys.stderr, msg … … 242 257 caller=service_caller('New'), responseBody="NewResponseBody") 243 258 except RPCException, e: 244 exit_with_fault(e )259 exit_with_fault(e, 'New (create)', opts) 245 260 except RuntimeError, e: 246 261 sys.exit("Error processing RPC: %s" % e) … … 248 263 if opts.debug > 1: print >>sys.stderr, resp_dict 249 264 265 proof = proof.from_dict(resp_dict.get('proof', {})) 266 if proof and opts.auth_log: 267 log_authentication(opts.auth_log, 'New (create)', 'succeeded', proof) 250 268 # Save the experiment ID certificate if we need it 251 269 try: … … 298 316 serialize_only=opts.serialize_only, 299 317 tracefile=opts.tracefile, 300 caller=service_caller('Create' ), responseBody="CreateResponseBody")318 caller=service_caller('Create', max_retries=1), responseBody="CreateResponseBody") 301 319 except RPCException, e: 302 exit_with_fault(e )320 exit_with_fault(e, 'Create', opts) 303 321 except RuntimeError, e: 304 322 sys.exit("Error processing RPC: %s" % e) … … 313 331 if e_fedid: print "fedid: %s" % e_fedid 314 332 if st: print "status: %s" % st 315 333 proof = proof.from_dict(resp_dict.get('proof', {})) 334 if proof and opts.auth_log: 335 log_authentication(opts.auth_log, 'Create', 'succeeded', proof) -
fedd/fedd_ftopo.py
rac15159 r0a49bd7 4 4 5 5 from federation import topdl 6 from federation.proof import proof 6 7 from federation.remote_service import service_caller 7 8 from federation.client_lib import client_opts, exit_with_fault, RPCException,\ 8 wrangle_standard_options, do_rpc, get_experiment_names, info_format 9 wrangle_standard_options, do_rpc, get_experiment_names, info_format, \ 10 log_authentication 9 11 10 12 class ftopo_opts(client_opts): … … 12 14 client_opts.__init__(self) 13 15 self.add_option("--experiment_cert", dest="exp_certfile", 14 type="string", help="experiment certificate file") 16 action='callback', callback=self.expand_file, type='str', 17 help="experiment certificate file") 15 18 self.add_option("--experiment_name", dest="exp_name", 16 19 type="string", help="human readable experiment name") … … 41 44 caller=service_caller('Info'), responseBody='InfoResponseBody') 42 45 except RPCException, e: 43 exit_with_fault(e )46 exit_with_fault(e, 'Ftopo', opts) 44 47 except RuntimeError, e: 45 48 sys.exit("Error processing RPC: %s" % e) … … 64 67 else: 65 68 sys.exit("Badly formatted response (no experiment descrption)!?") 69 proof = proof.from_dict(resp_dict.get('proof', {})) 70 if proof and opts.auth_log: 71 log_authentication(opts.auth_log, 'Ftopo', 'succeeded', proof) -
fedd/fedd_image.py
rac15159 r0a49bd7 8 8 9 9 from federation import topdl 10 from federation.proof import proof 10 11 from federation.remote_service import service_caller 11 12 from federation.client_lib import client_opts, exit_with_fault, RPCException, \ 12 wrangle_standard_options, do_rpc, get_experiment_names, save_certfile 13 wrangle_standard_options, do_rpc, get_experiment_names, save_certfile,\ 14 log_authentication 13 15 14 16 … … 17 19 client_opts.__init__(self) 18 20 self.add_option("--experiment_cert", dest="exp_certfile", 19 type="string", help="experiment certificate file") 21 action='callback', callback=self.expand_file, type='str', 22 help="experiment certificate file") 20 23 self.add_option("--experiment_name", dest="exp_name", 21 24 type="string", help="human readable experiment name") 22 self.add_option("--output", dest="outfile", type="string", 25 self.add_option("--output", dest="outfile", 26 action='callback', callback=self.expand_file, type='str', 23 27 help="output image file") 24 28 self.add_option("--format", dest="format", type="choice", … … 38 42 help="Size of output in pixels (diagrams are square") 39 43 self.add_option("--file", dest="file", 44 action='callback', callback=self.expand_file, type='str', 40 45 help="experiment description file") 41 46 self.add_option("--group", dest="group", action="append", default=[], … … 293 298 caller=service_caller('Info'), responseBody="InfoResponseBody") 294 299 300 proof = proof.from_dict(resp_dict.get('proof', {})) 301 if proof and opts.auth_log: 302 log_authentication(opts.auth_log, 'Image', 'succeeded', proof) 295 303 return extract_topo_from_message(resp_dict, opts.serialize_only) 296 304 … … 333 341 (opts, args) = parser.parse_args() 334 342 335 # Note that if we're converting a local topdl file, the absence of a cert may336 # not be a big deal. It's checked if needed below343 # Note that if we're converting a local topdl file, the absence of a cert or 344 # abac directory may not be a big deal. It's checked if needed below 337 345 try: 338 346 cert, fid, url = wrangle_standard_options(opts) 339 347 except RuntimeError, e: 340 348 cert = None 341 print >>sys.stderr, "Warning: %s e"349 print >>sys.stderr, "Warning: %s" % e 342 350 343 351 … … 371 379 top = get_experiment_topo(opts, cert, url) 372 380 except RPCException, e: 373 exit_with_fault(e )381 exit_with_fault(e, 'image', opts) 374 382 except RuntimeError, e: 375 383 sys.exit("%s" % e) … … 383 391 except RPCException, e: 384 392 print >>sys.stderr, "Cannot extract a topology from %s" % opts.file 385 exit_with_fault(e )393 exit_with_fault(e, 'image', opts) 386 394 except RuntimeError, e: 387 395 sys.exit("Cannot extract a topology from %s: %s" % (opts.file, e)) -
fedd/fedd_info.py
rac15159 r0a49bd7 3 3 import sys 4 4 5 from federation.proof import proof 5 6 from federation.remote_service import service_caller 6 7 from federation.client_lib import client_opts, exit_with_fault, RPCException,\ 7 wrangle_standard_options, do_rpc, get_experiment_names, info_format 8 wrangle_standard_options, do_rpc, get_experiment_names, info_format, \ 9 log_authentication 8 10 9 11 class exp_data_opts(client_opts): … … 11 13 client_opts.__init__(self) 12 14 self.add_option("--experiment_cert", dest="exp_certfile", 13 type="string", help="experiment certificate file") 15 action='callback', callback=self.expand_file, type='str', 16 help="experiment certificate file") 14 17 self.add_option("--experiment_name", dest="exp_name", 15 18 type="string", help="human readable experiment name") … … 42 45 caller=service_caller('Info'), responseBody='InfoResponseBody') 43 46 except RPCException, e: 44 exit_with_fault(e )47 exit_with_fault(e, 'Info', opts) 45 48 except RuntimeError, e: 46 49 sys.exit("Error processing RPC: %s" % e) … … 52 55 except RuntimeError, e: 53 56 print >>sys.stderr, "Warning: %s" % e 57 proof = proof.from_dict(resp_dict.get('proof', {})) 58 if proof and opts.auth_log: 59 log_authentication(opts.auth_log, 'Info', 'succeeded', proof) -
fedd/fedd_multiinfo.py
rac15159 r0a49bd7 10 10 import time 11 11 12 from federation.proof import proof 12 13 from federation.remote_service import service_caller 13 14 from federation.client_lib import client_opts, exit_with_fault, RPCException,\ 14 wrangle_standard_options, do_rpc, info_format 15 wrangle_standard_options, do_rpc, info_format, log_authentication 15 16 16 17 class exp_data_opts(client_opts): … … 25 26 parser = exp_data_opts() 26 27 (opts, args) = parser.parse_args() 27 cert, fid, url = wrangle_standard_options(opts) 28 try: 29 cert, fid, url = wrangle_standard_options(opts) 30 except RuntimeError, e: 31 sys.exit("%s" %e) 28 32 29 33 try: … … 35 39 responseBody='MultiInfoResponseBody') 36 40 except RPCException, e: 37 exit_with_fault(e )41 exit_with_fault(e, 'MultiInfo', opts) 38 42 except RuntimeError, e: 39 43 sys.exit("Error processing RPC: %s" % e) … … 44 48 formatter(i, d) 45 49 print "---" 50 proof = proof.from_dict(resp_dict.get('proof', {})) 51 if proof and opts.auth_log: 52 log_authentication(opts.auth_log, 'MultiInfo', 'succeeded', proof) -
fedd/fedd_multistatus.py
rac15159 r0a49bd7 3 3 import sys 4 4 5 from federation.proof import proof 5 6 from federation.remote_service import service_caller 6 7 from federation.client_lib import client_opts, exit_with_fault, RPCException, \ 7 wrangle_standard_options, do_rpc, get_experiment_names 8 wrangle_standard_options, do_rpc, get_experiment_names, \ 9 log_authentication 8 10 9 11 parser = client_opts() 10 12 (opts, args) = parser.parse_args() 11 cert, fid, url = wrangle_standard_options(opts) 13 try: 14 cert, fid, url = wrangle_standard_options(opts) 15 except RuntimeError, e: 16 sys.exit("%s" %e) 12 17 13 18 try: … … 19 24 responseBody='MultiInfoResponseBody') 20 25 except RPCException, e: 21 exit_with_fault(e )26 exit_with_fault(e, 'MultiInfo', opts) 22 27 except RuntimeError, e: 23 28 sys.exit("Error processing RPC: %s" % e) … … 30 35 print ":".join([ l or "" , "%s" % (f or "") , 31 36 exp.get('experimentStatus', "") ]) 37 proof = proof.from_dict(resp_dict.get('proof', {})) 38 if proof and opts.auth_log: 39 log_authentication(opts.auth_log, 'MultiInfo', 'succeeded', proof) -
fedd/fedd_new.py
rac15159 r0a49bd7 2 2 3 3 import sys 4 from datetime import datetime 4 5 5 6 from federation.fedid import fedid, generate_fedid 6 7 from federation.remote_service import service_caller 8 from federation.proof import proof 7 9 from federation.client_lib import client_opts, exit_with_fault, RPCException, \ 8 10 wrangle_standard_options, do_rpc, get_experiment_names, \ 9 save_certfile, get_abac_certs 10 11 save_certfile, get_abac_certs, log_authentication 11 12 12 13 class new_opts(client_opts): … … 14 15 client_opts.__init__(self) 15 16 self.add_option("--experiment_cert", dest="out_certfile", 16 type="string", help="output certificate file") 17 action='callback', callback=self.expand_file, type='str', 18 help="output certificate file") 17 19 self.add_option("--experiment_name", dest="exp_name", 18 20 type="string", help="Suggested experiment name") … … 24 26 (opts, args) = parser.parse_args() 25 27 26 cert, fid, url = wrangle_standard_options(opts)27 28 try: 29 cert, fid, url = wrangle_standard_options(opts) 28 30 acerts = get_abac_certs(opts.abac_dir) 29 31 except EnvironmentError, e: 30 32 sys.exit('%s: %s' % (e.filename, e.strerror)) 33 except RuntimeError, e: 34 sys.exit("%s" %e) 31 35 32 36 out_certfile = opts.out_certfile … … 55 59 caller=service_caller("New"), responseBody='NewResponseBody') 56 60 except RPCException, e: 57 exit_with_fault(e )61 exit_with_fault(e, 'New', opts) 58 62 except RuntimeError, e: 59 63 sys.exit("Error processing RPC: %s" % e) … … 72 76 e_fedid, e_local = get_experiment_names(resp_dict.get('experimentID', None)) 73 77 st = resp_dict.get('experimentStatus', None) 78 proof = proof.from_dict(resp_dict.get('proof', {})) 74 79 75 80 if e_local: print "localname: %s" % e_local 76 81 if e_fedid: print "fedid: %s" % e_fedid 77 82 if st: print "status: %s" % st 83 if proof and opts.auth_log: 84 log_authentication(opts.auth_log, 'New', 'succeeded', proof) -
fedd/fedd_ns2topdl.py
rac15159 r0a49bd7 4 4 5 5 from federation import topdl 6 from federation.proof import proof 6 7 from federation.remote_service import service_caller 7 8 from federation.client_lib import client_opts, exit_with_fault, RPCException, \ … … 12 13 client_opts.__init__(self) 13 14 self.add_option("--file", dest="file", 15 action='callback', callback=self.expand_file, type='str', 14 16 help="experiment description file") 15 17 self.add_option("--output", dest="outfile", type="string", … … 19 21 (opts, args) = parser.parse_args() 20 22 21 cert, fid, url = wrangle_standard_options(opts) 23 try: 24 cert, fid, url = wrangle_standard_options(opts) 25 except RuntimeError, e: 26 sys.exit("%s" %e) 22 27 23 28 if opts.file: … … 41 46 responseBody="Ns2TopdlResponseBody") 42 47 except RPCException, e: 43 exit_with_fault(e )48 exit_with_fault(e, 'Ns2Topdl', opts) 44 49 except RuntimeError, e: 45 50 sys.exit("Error processing RPC: %s" % e) … … 65 70 else: 66 71 print topdl.topology_to_xml(top, top="experiment") 72 proof = proof.from_dict(resp_dict.get('proof', {})) 73 if proof and opts.auth_log: 74 log_authentication(opts.auth_log, 'New (create)', 'succeeded', proof) -
fedd/fedd_spewlog.py
rac15159 r0a49bd7 4 4 import time 5 5 6 from federation.proof import proof 6 7 from federation.remote_service import service_caller 7 8 from federation.client_lib import client_opts, exit_with_fault, RPCException, \ … … 12 13 client_opts.__init__(self) 13 14 self.add_option("--experiment_cert", dest="exp_certfile", 14 type="string", help="experiment name certificate file") 15 action='callback', callback=self.expand_file, type='str', 16 help="experiment name certificate file") 15 17 self.add_option("--experiment_name", dest="exp_name", 16 18 type="string", help="human readable experiment name") 17 19 self.add_option("--logfile", dest="logfile", default=None, 20 action='callback', callback=self.expand_file, type='str', 18 21 help="File to write log to") 19 22 self.add_option('--update_time', dest='update', type='int', default=10, … … 25 28 (opts, args) = parser.parse_args() 26 29 27 cert, fid, url = wrangle_standard_options(opts) 30 try: 31 cert, fid, url = wrangle_standard_options(opts) 32 except RuntimeError, e: 33 sys.exit("%s" %e) 28 34 29 35 if opts.exp_name and opts.exp_certfile: … … 58 64 caller=service_caller('Info'), responseBody="InfoResponseBody") 59 65 except RPCException, e: 60 exit_with_fault(e )66 exit_with_fault(e, 'Info (spewlog)', opts) 61 67 except RuntimeError, e: 62 68 sys.exit("Error processing RPC: %s" % e) 69 70 proof = proof.from_dict(resp_dict.get('proof', {})) 71 if proof and opts.auth_log: 72 log_authentication(opts.auth_log, 'Info (spewlog)', 'succeeded', proof) 63 73 64 74 if not opts.serialize_only: -
fedd/fedd_terminate.py
rac15159 r0a49bd7 4 4 5 5 from federation.fedid import fedid 6 from federation.proof import proof 6 7 from federation.remote_service import service_caller 7 8 from federation.client_lib import client_opts, exit_with_fault, RPCException, \ 8 wrangle_standard_options, do_rpc 9 wrangle_standard_options, do_rpc, log_authentication 9 10 10 11 class terminate_opts(client_opts): … … 12 13 client_opts.__init__(self) 13 14 self.add_option("--experiment_cert", dest="exp_certfile", 14 type="string", help="experiment certificate file") 15 action='callback', callback=self.expand_file, type='str', 16 help="experiment certificate file") 15 17 self.add_option("--experiment_name", dest="exp_name", 16 18 type="string", help="human readable experiment name") … … 19 21 help="Force termination if experiment is in strange state") 20 22 self.add_option("--logfile", dest="logfile", default=None, 23 action='callback', callback=self.expand_file, type='str', 21 24 help="File to write log to") 22 25 self.add_option("--print_log", dest="print_log", default=False, … … 27 30 parser = terminate_opts() 28 31 (opts, args) = parser.parse_args() 29 cert, fid, url = wrangle_standard_options(opts) 32 33 try: 34 cert, fid, url = wrangle_standard_options(opts) 35 except RuntimeError, e: 36 sys.exit("%s" %e) 30 37 31 38 if opts.exp_name and opts.exp_certfile: … … 60 67 responseBody='TerminateResponseBody') 61 68 except RPCException, e: 62 exit_with_fault(e )69 exit_with_fault(e, 'Terminate', opts) 63 70 except RuntimeError, e: 64 71 sys.exit("Error processing RPC: %s" % e) … … 72 79 out.close() 73 80 sys.exit("No log returned") 81 proof = proof.from_dict(resp_dict.get('proof', {})) 82 if proof and opts.auth_log: 83 log_authentication(opts.auth_log, 'Terminate', 'succeeded', proof) -
fedd/fedd_to_abac.py
rac15159 r0a49bd7 7 7 import os.path 8 8 import subprocess 9 from tempfile import mkdtemp 9 10 10 11 from string import join 11 from optparse import OptionParser 12 13 from federation.util import abac_pem_type, abac_split_cert 14 15 class Parser( OptionParser):12 13 from federation.authorizer import abac_authorizer 14 from federation.util import abac_pem_type, abac_split_cert, file_expanding_opts 15 16 class Parser(file_expanding_opts): 16 17 def __init__(self): 17 OptionParser.__init__(self)18 file_expanding_opts.__init__(self) 18 19 self.add_option('--cert', dest='cert', default=None, 20 action='callback', callback=self.expand_file, type='str', 19 21 help='my fedid as an X.509 certificate') 20 22 self.add_option('--key', dest='key', default=None, 23 action='callback', callback=self.expand_file, type='str', 21 24 help='key for the certificate') 22 25 self.add_option('--dir', dest='dir', default=None, 26 action='callback', callback=self.expand_file, type='str', 23 27 help='Output directory for credentials') 24 self.add_option('--make -dir', action='store_true', dest='make_dir',28 self.add_option('--make_dir', action='store_true', dest='make_dir', 25 29 default=False, help='Create the --dir directory') 26 30 self.add_option('--debug', action='store_true', dest='debug', 27 31 default=False, help='Just print the creddy commands') 32 self.add_option('--policy_only', action='store_const', const=False, 33 dest='make_authorizer', default=True, 34 help='Only create the directory of certs, " + \ 35 "do not create an authorizer') 36 self.add_option('--update', action='store_const', const=True, 37 dest='update_authorizer', default=False, 38 help='Add the generated policy to an existing authorizer') 28 39 29 40 class identity: … … 38 49 return "%s: %s" % (self.name, join(self.roles, ', ')) 39 50 40 comment_re = re.compile('^\s*#|^$') 41 fedid_str = 'fedid:([0-9a-fA-F]{40})' 42 id_str = '[a-zA-Z][\w_-]*' 43 single_re = re.compile('\s*%s\s*->\s*(%s)' % (fedid_str, id_str)) 44 double_re = re.compile('\s*%s\s*->\s*\((%s)\s*,\s*(%s)\)' % \ 45 (fedid_str, id_str, id_str)) 46 bad_role = re.compile('[^a-zA-Z0-9_]+') 51 def clear_dir(dir): 52 for path, dirs, files in os.walk(dir, topdown=False): 53 for f in files: os.unlink(os.path.join(path, f)) 54 for d in dirs: os.rmdir(os.path.join(path, d)) 55 56 def parse_configs(files): 57 """ 58 Step through each file pulling the roles out of the database lines, if any, 59 and creating (or appending to) identity objects, one identity in a dict for 60 each fedid. Return that dict. May raise an exception when file 61 difficulties occur. 62 """ 63 comment_re = re.compile('^\s*#|^$') 64 fedid_str = 'fedid:([0-9a-fA-F]{40})' 65 id_str = '[a-zA-Z][\w_-]*' 66 single_re = re.compile('\s*%s\s*->\s*(%s)' % (fedid_str, id_str)) 67 double_re = re.compile('\s*%s\s*->\s*\((%s)\s*,\s*(%s)\)' % \ 68 (fedid_str, id_str, id_str)) 69 bad_role = re.compile('[^a-zA-Z0-9_]+') 70 71 roles = { } 72 73 for fn in files: 74 f = open(fn, "r") 75 for l in f: 76 id = None 77 for r in (comment_re, single_re, double_re): 78 m = r.match(l) 79 if m: 80 # NB, the comment_re has no groups 81 if m.groups(): 82 g = m.groups() 83 id = g[0] 84 r = [ bad_role.sub('_', x) for x in g[1:] ] 85 break 86 else: 87 print 'Unmatched line: %s' % l 88 89 if id: 90 # New and create are implicit. >sigh< 91 r.extend(('new', 'create')) 92 if id in roles: roles[id].add_roles(r) 93 else: roles[id] = identity(r[0], r) 94 95 return roles 96 97 def make_credentials(roles, cert, key, creds_dir, debug): 98 """ 99 From the dict of identities, indexed by fedid, call creddy to create the 100 ABAC certificates. Return a list of the created files. If debug is true, 101 just print the creddy commands. 102 """ 103 credfiles = [] 104 for k, id in roles.items(): 105 for i, r in enumerate(id.roles): 106 cf = '%s/%s%03d_attr.der' % \ 107 (creds_dir or 'new_cert_dir', id.name, i) 108 cmd = ['creddy', '--attribute', 109 '--issuer=%s' % (cert or 'cert_file'), 110 '--key=%s' % (key or 'key_file'), '--role=%s' % r, 111 '--subject-id=%s' % k, '--out=%s' % cf ] 112 if debug: 113 print join(cmd) 114 else: 115 rv = subprocess.call(cmd) 116 if rv != 0: 117 raise RuntimeError('%s failed: %d' % (join(cmd), rv)) 118 else: 119 credfiles.append(cf) 120 return credfiles 47 121 48 122 parser = Parser() … … 51 125 delete_certs = False 52 126 53 127 if not opts.make_authorizer and opts.update_authorizer: 128 sys.exit('--policy_only and --update are in conflict. Pick one.') 54 129 55 130 if opts.key: 56 131 if os.access(opts.key, os.R_OK): key = opts.key 57 132 else: sys.exit('Cannot read %s (key file)' % opts.key) 133 134 if opts.make_authorizer: 135 creds_dir = mkdtemp() 136 delete_creds = True 137 else: 138 creds_dir = opts.dir 139 delete_creds = False 140 141 if opts.cert: 142 if os.access(opts.cert, os.R_OK): 143 if not key: 144 if abac_pem_type(opts.cert) == 'both': 145 key, cert = abac_split_cert(opts.cert) 146 delete_certs = True 147 else: 148 cert = opts.cert 149 else: 150 sys.exit('Cannot read %s (certificate file)' % opts.cert) 151 152 if any([ x is None for x in (cert, opts.dir, key)]): 153 print >>sys.stderr, "Need output dir, certificate and key to make creds" 154 print >>sys.stderr, "Reverting to debug mode" 155 debug = True 156 else: 157 debug = opts.debug 58 158 59 159 if opts.dir: … … 70 170 sys.exit('%s is not writable' % opts.dir) 71 171 72 if opts.cert: 73 if os.access(opts.cert, os.R_OK): 74 if not key: 75 if abac_pem_type(opts.cert) == 'both': 76 key, cert = abac_split_cert(opts.cert) 77 delete_certs = True 78 else: 79 cert = opts.cert 80 else: 81 sys.exit('Cannot read %s (certificate file)' % opts.cert) 82 83 if any([ x is None for x in (cert, opts.dir, key)]): 84 print >>sys.stderr, "Need output dir, certificate and key to make creds" 85 print >>sys.stderr, "Reverting to debug mode" 86 debug = True 87 else: 88 debug = opts.debug 89 90 roles = { } 172 91 173 try: 92 for fn in args: 93 try: 94 f = open(fn, "r") 95 for l in f: 96 id = None 97 for r in (comment_re, single_re, double_re): 98 m = r.match(l) 99 if m: 100 if m.groups(): 101 g = m.groups() 102 id = g[0] 103 r = [ bad_role.sub('_', x) for x in g[1:] ] 104 break 105 else: 106 print 'Unmatched line: %s' % l 107 if id: 108 # New and create are implicit. >sigh< 109 r.extend(('new', 'create')) 110 if id in roles: roles[id].add_roles(r) 111 else: roles[id] = identity(r[0], r) 112 113 except EnvironmentError, e: 114 print >>sys.stderr, 'Cannot open file (%s): %s' % \ 115 (e.filename, e.strerror) 116 174 roles = parse_configs(args) 117 175 if not roles: 118 176 print >>sys.stderr, "No roles found. Did you specify a configuration?" 119 177 120 for k, id in roles.items(): 121 for i, r in enumerate(id.roles): 122 cmd = ['creddy', '--attribute', 123 '--issuer=%s' % (cert or 'cert_file'), 124 '--key=%s' % (key or 'key_file'), '--role=%s' % r, 125 '--subject-id=%s' % k, 126 '--out=%s/%s%03d_attr.der' % \ 127 (opts.dir or 'new_cert_dir', id.name, i)] 178 try: 179 credfiles = make_credentials(roles, cert, key, creds_dir, debug) 180 181 if opts.make_authorizer: 128 182 if debug: 129 print join(cmd) 183 print >>sys.stderr, 'Debug mode, no authorizer created' 184 elif opts.update_authorizer: 185 operation = 'updat' 186 a = abac_authorizer(load=opts.dir) 187 a.import_credentials(file_list=credfiles) 188 a.save() 130 189 else: 131 rv = subprocess.call(cmd) 132 if rv != 0: 133 sys.exit('%s failed: %d' % (join(cmd), rv)) 190 operation = 'creat' 191 a = abac_authorizer(key=opts.key, me=opts.cert, 192 certs=creds_dir, save=opts.dir) 193 a.save() 194 except EnvironmentError, e: 195 sys.exit("Can't create or write %s: %s" % (e.filename, 196 e.strerror)) 197 except abac_authorizer.bad_cert_error, e: 198 sys.exit("Error %sing authorizer: %s" % (op, e)) 199 except RuntimeError, e: 200 sys.exit('%s' % e) 201 134 202 finally: 135 203 if delete_certs: 136 204 if cert: os.unlink(cert) 137 205 if key: os.unlink(key) 206 if delete_creds: 207 clear_dir(creds_dir) 208 os.rmdir(creds_dir) -
fedd/federation/access.py
rac15159 r0a49bd7 234 234 "Unpickling failed: %s") % e) 235 235 236 def append_allocation_authorization(self, aid, attrs, 237 need_state_lock=False, write_state_file=False, state_attr='state'): 238 """ 239 Append the authorization information to system state. By default we 240 assume this is called with the state lock and with a write of the state 241 file in the near future, need_state_lock and write_state_file can 242 override this. The state_attr is the attribute in the access class 243 that holds the per allocation information. Some complex classes use 244 different names for the dict. 245 """ 246 247 for p, a in attrs: 248 self.auth.set_attribute(p, a) 249 self.auth.save() 250 251 if need_state_lock: self.state_lock.acquire() 252 d = getattr(self, state_attr) 253 if aid in d and 'auth' in d[aid]: 254 d[aid]['auth'].update(attrs) 255 if write_state_file: self.write_state() 256 if need_state_lock: self.state_lock.release() 257 258 def clear_allocation_authorization(self, aid, need_state_lock=False, 259 write_state_file=False, state_attr='state'): 260 """ 261 Attrs is a set of attribute principal pairs that need to be removed 262 from the authenticator. Remove them and save the authenticator. See 263 append_allocation_authorization for the various overrides. 264 """ 265 266 if need_state_lock: self.state_lock.acquire() 267 d = getattr(self, state_attr) 268 if aid in d and 'auth' in d[aid]: 269 for p, a in d[aid]['auth']: 270 self.auth.unset_attribute(p, a) 271 d[aid]['auth'] = set() 272 if write_state_file: self.write_state() 273 if need_state_lock: self.state_lock.release() 274 self.auth.save() 275 236 276 def lookup_access(self, req, fid, filter=None, compare=None): 237 277 """ … … 261 301 # Check every attribute that we know how to map and take the first 262 302 # success. 303 fail_proofs = [ ] 263 304 for attr in check: 264 if self.auth.check_attribute(fid, attr.attr): 305 access_ok, proof = self.auth.check_attribute(fid, attr.attr, 306 with_proof=True) 307 if access_ok: 265 308 self.log.debug("Access succeeded for %s %s" % (attr.attr, fid)) 266 309 # XXX: needs to deal with dynamics 267 310 return copy.copy(attr.value), (False, False, False), \ 268 [ fid ] 311 [ fid ], proof 269 312 else: 313 fail_proofs.append(proof) 270 314 self.log.debug("Access failed for %s %s" % (attr.attr, fid)) 271 315 else: 272 raise service_error(service_error.access, "Access denied") 316 raise service_error(service_error.access, "Access denied", 317 proof=fail_proofs) 273 318 274 319 … … 408 453 return (exp, state) 409 454 410 def build_access_response(self, alloc_id, ap, services ):455 def build_access_response(self, alloc_id, ap, services, proof): 411 456 """ 412 457 Create the SOAP response. … … 421 466 msg = { 422 467 'allocID': alloc_id, 468 'proof': proof.to_dict(), 423 469 'fedAttr': [ 424 470 { 'attribute': 'domain', 'value': self.domain } , … … 730 776 except EnvironmentError, e: 731 777 self.log.error("Error deleting directory tree in %s" % e); 778 779 def RequestAccess(self, req, fid): 780 """ 781 Handle an access request. Success here maps the requester into the 782 local access control space and establishes state about that user keyed 783 to a fedid. We also save a copy of the certificate underlying that 784 fedid so this allocation can access configuration information and 785 shared parameters on the experiment controller. 786 """ 787 788 # The dance to get into the request body 789 if req.has_key('RequestAccessRequestBody'): 790 req = req['RequestAccessRequestBody'] 791 else: 792 raise service_error(service_error.req, "No request!?") 793 794 # Base class lookup routine. If this fails, it throws a service 795 # exception denying access that triggers a fault response back to the 796 # caller. 797 found, match, owners, proof = self.lookup_access(req, fid) 798 self.log.info( 799 "[RequestAccess] Access granted to %s with local creds %s" % \ 800 (match, found)) 801 # Make a fedid for this allocation 802 allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log) 803 aid = unicode(allocID) 804 805 # Store the data about this allocation: 806 self.state_lock.acquire() 807 self.state[aid] = { } 808 self.state[aid]['user'] = found 809 self.state[aid]['owners'] = owners 810 self.state[aid]['auth'] = set() 811 # Authorize the creating fedid and the principal representing the 812 # allocation to manipulate it. 813 self.append_allocation_authorization(aid, 814 ((fid, allocID), (allocID, allocID))) 815 self.write_state() 816 self.state_lock.release() 817 818 # Create a directory to stash the certificate in, ans stash it. 819 try: 820 f = open("%s/%s.pem" % (self.certdir, aid), "w") 821 print >>f, alloc_cert 822 f.close() 823 except EnvironmentError, e: 824 raise service_error(service_error.internal, 825 "Can't open %s/%s : %s" % (self.certdir, aid, e)) 826 self.log.debug('[RequestAccess] Returning allocation ID: %s' % allocID) 827 return { 'allocID': { 'fedid': allocID }, 'proof': proof.to_dict() } 828 829 def ReleaseAccess(self, req, fid): 830 """ 831 Release the allocation granted earlier. Access to the allocation is 832 checked and if valid, the state and cached certificate are destroyed. 833 """ 834 # The dance to get into the request body 835 if req.has_key('ReleaseAccessRequestBody'): 836 req = req['ReleaseAccessRequestBody'] 837 else: 838 raise service_error(service_error.req, "No request!?") 839 840 # Pull a key out of the request. One can request to delete an 841 # allocation by a local human readable name or by a fedid. This finds 842 # both choices. 843 try: 844 if 'localname' in req['allocID']: 845 auth_attr = aid = req['allocID']['localname'] 846 elif 'fedid' in req['allocID']: 847 aid = unicode(req['allocID']['fedid']) 848 auth_attr = req['allocID']['fedid'] 849 else: 850 raise service_error(service_error.req, 851 "Only localnames and fedids are understood") 852 except KeyError: 853 raise service_error(service_error.req, "Badly formed request") 854 855 self.log.debug("[ReleaseAccess] deallocation requested for %s", aid) 856 # Confirm access 857 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 858 with_proof=True) 859 if not access_ok: 860 self.log.debug("[ReleaseAccess] deallocation denied for %s", aid) 861 raise service_error(service_error.access, "Access Denied", 862 proof=proof) 863 864 # If there is an allocation in the state, delete it. Note the locking. 865 self.state_lock.acquire() 866 if aid in self.state: 867 self.log.debug("[ReleaseAccess] Found allocation for %s" %aid) 868 self.clear_allocation_authorization(aid) 869 del self.state[aid] 870 self.write_state() 871 self.state_lock.release() 872 # And remove the access cert 873 cf = "%s/%s.pem" % (self.certdir, aid) 874 self.log.debug("[ReleaseAccess] Removing %s" % cf) 875 os.remove(cf) 876 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } 877 else: 878 self.state_lock.release() 879 raise service_error(service_error.req, "No such allocation") -
fedd/federation/authorizer.py
rac15159 r0a49bd7 1 1 #/usr/local/bin/python 2 2 3 from string import join4 3 from tempfile import mkstemp 5 4 from subprocess import call … … 12 11 from service_error import service_error 13 12 from util import abac_pem_type, abac_split_cert 13 from proof import proof 14 14 15 15 … … 116 116 if attrs: attrs.discard(attr) 117 117 118 def check_attribute(self, name, attr ):118 def check_attribute(self, name, attr, with_proof=False): 119 119 """ 120 120 Return True if name has attr (or if attr is global). Tuple names match … … 130 130 self.valid_name(name) 131 131 if attr in self.globals: 132 return True 132 if with_proof: return True, proof("me", name, attr) 133 else: return True 133 134 134 135 if isinstance(name, tuple): … … 137 138 if self.attrs.has_key(lookup): 138 139 if attr in self.attrs[lookup]: 139 return True 140 else: 141 return attr in self.attrs.get(self.auth_name(name), set()) 140 if with_proof: return True, proof("me", name, attr) 141 else: return True 142 # Drop through 143 if with_proof: return False, proof("me", name, attr) 144 else: return False 145 else: 146 if with_proof: 147 return attr in self.attrs.get(self.auth_name(name), set()), \ 148 proof("me", name, attr) 149 else: 150 return attr in self.attrs.get(self.auth_name(name), set()) 142 151 143 152 def set_global_attribute(self, attr): … … 209 218 if self.me is not None and abac_pem_type(self.me) == 'both': 210 219 if self.save_dir: 211 self.key, self.me = abac_split_cert(self.me, 212 keyfile="%s/key.pem" % self.save_dir, 213 certfile = "%s/cert.pem" % self.save_dir) 220 keyfile="%s/key.pem" % self.save_dir 221 certfile = "%s/cert.pem" % self.save_dir 222 223 # Clear a spot for the new key and cert files. 224 for fn in (keyfile, certfile): 225 if os.access(fn, os.F_OK): 226 os.unlink(fn) 227 228 self.key, self.me = abac_split_cert(self.me, keyfile, certfile) 214 229 else: 215 230 raise abac_authorizer.bad_cert_error("Combination " + \ … … 223 238 if rv != 0: 224 239 raise abac_authorizer.bad_name( 225 'Cannot load identity from %s' % me .cert)240 'Cannot load identity from %s' % me) 226 241 else: 227 242 self.fedid = None … … 235 250 if load: 236 251 self.load(load) 252 253 # Modify the pickling operations so that the context and lock are not 254 # pickled 255 256 def __getstate__(self): 257 d = self.__dict__.copy() 258 del d['lock'] 259 del d['context'] 260 return d 261 262 def __setstate__(self, d): 263 # Import everything from the pickle dict (except what we excluded in 264 # __getstate__) 265 self.__dict__.update(d) 266 # Initialize the unpicklables 267 self.context = ABAC.Context() 268 self.lock = Lock() 237 269 238 270 @staticmethod … … 352 384 353 385 354 def check_attribute(self, name, attr): 355 # XXX proof soon 386 def check_attribute(self, name, attr, with_proof=False): 356 387 if isinstance(name, tuple): 357 388 raise abac_authorizer.bad_name( … … 376 407 # Sigh. Unicode vs swig and swig seems to lose. Make sure 377 408 # everything we pass into ABAC is a str not a unicode. 378 rv, p roof= self.context.query(a, n)409 rv, p = self.context.query(a, n) 379 410 # XXX delete soon 380 if not rv and attr in self.globals: rv = True 381 self.lock.release() 382 383 return rv 411 if not rv and attr in self.globals: 412 rv = True 413 p = None 414 self.lock.release() 415 if with_proof: return rv, proof(self.fedid, name, a, p) 416 else: return rv 384 417 385 418 def set_global_attribute(self, attr): … … 421 454 if not os.access(dir, os.F_OK): 422 455 os.mkdir(dir) 423 # These are unpicklable, so set them aside424 context = self.context425 lock = self.lock426 self.context = None427 self.lock = None428 456 429 457 f = open("%s/state" % dir, "w") … … 433 461 if not os.access("%s/certs" %dir, os.F_OK): 434 462 os.mkdir("%s/certs" % dir) 435 seenid = set() 436 seenattr = set() 437 438 #restore unpicklable state 439 self.context = context 440 self.lock = lock 441 #remove old certs 463 464 # Clear the certs subdir 442 465 for fn in [ f for f in os.listdir("%s/certs" % dir) \ 443 466 if abac_authorizer.cred_file_re.match(f)]: 444 467 os.unlink('%s/certs/%s' % (dir, fn)) 468 469 # Save the context 445 470 ii = 0 446 471 ai = 0 472 seenid = set() 473 seenattr = set() 447 474 for c in self.context.credentials(): 448 475 id = c.issuer_cert() … … 463 490 seenattr.add(attr) 464 491 except EnvironmentError, e: 465 # If we've mislaid self.lock, release lock (they're the same object) 466 if self.lock: self.lock.release() 467 elif lock: lock.release() 492 self.lock.release() 468 493 raise e 469 494 except pickle.PickleError, e: 470 # If we've mislaid self.lock, release lock (they're the same object) 471 if self.lock: self.lock.release() 472 elif lock: lock.release() 495 self.lock.release() 473 496 raise e 474 497 self.lock.release() -
fedd/federation/client_lib.py
rac15159 r0a49bd7 7 7 8 8 from string import join 9 from datetime import datetime 9 10 10 11 11 12 from fedid import fedid 12 from util import fedd_ssl_context 13 from util import fedd_ssl_context, file_expanding_opts 13 14 from remote_service import service_caller 14 15 from service_error import service_error … … 17 18 18 19 19 class client_opts( OptionParser):20 class client_opts(file_expanding_opts): 20 21 """ 21 22 Standatd set of options that all clients talking to fedd can probably use. 22 23 Client code usually specializes this. 23 24 """ 25 24 26 def __init__(self): 25 OptionParser.__init__(self, usage="%prog [opts] (--help for details)", 27 file_expanding_opts.__init__(self, 28 usage="%prog [opts] (--help for details)", 26 29 version="0.1") 27 30 28 self.add_option("--cert", action="store", dest="cert", 31 self.add_option("--cert", action="callback", dest="cert", 32 callback=self.expand_file, 29 33 type="string", help="my certificate file") 30 self.add_option("--abac", action="store", dest="abac_dir", 31 type="string", help="Directory with abac certs") 34 self.add_option("--auth_log", action="callback", dest="auth_log", 35 callback=self.expand_file, default=None, 36 type="string", help="Log authentication decisions to this file") 37 self.add_option("--abac", action="callback", dest="abac_dir", 38 callback=self.expand_file, 39 type="string", default=os.path.expanduser('~/.abac'), 40 help="Directory with abac certs") 41 self.add_option('--no_abac', action='store_const', const=None, 42 dest='abac_dir', help='Do not use abac authorization') 32 43 self.add_option( "--debug", action="count", dest="debug", 33 44 default=0, help="Set debug. Repeat for more information") … … 35 46 dest="serialize_only", default=False, 36 47 help="Print the SOAP request that would be sent and exit") 37 self.add_option("--trusted", action="store", dest="trusted", 48 self.add_option("--trusted", action="callback", dest="trusted", 49 callback=self.expand_file, 38 50 type="string", help="Trusted certificates (required)") 39 51 self.add_option("--url", action="store", dest="url", … … 45 57 const=sys.stderr, help="Print SOAP exchange to stderr") 46 58 47 def exit_with_fault(exc, out=sys.stderr): 59 def log_authentication(fn, action, outcome, proof): 60 f = open(fn, 'a') 61 print >>f, '%s %s at %s' % (action, outcome, datetime.now()) 62 if isinstance(proof, list): 63 for p in proof: 64 print >>f, p.to_xml() 65 else: 66 print >>f, proof.to_xml() 67 f.close() 68 69 70 def exit_with_fault(exc, action, opts, out=sys.stderr): 48 71 """ 49 72 Print an error message and exit. exc is the RPCException that caused the … … 64 87 code = -1 65 88 89 if exc.code == service_error.access and opts.auth_log: 90 try: 91 log_authentication(opts.auth_log, action, 'failed', exc.proof) 92 except EnvironmentError, e: 93 print >>sys.stderr, "Failed to log to %s: %s" % \ 94 (e.filename, e.strerror) 95 66 96 print>>out, codestr 67 97 print>>out, "Description: %s" % exc.desc … … 73 103 XMLPRC calls. 74 104 """ 75 def __init__(self, desc=None, code=None, errstr=None ):105 def __init__(self, desc=None, code=None, errstr=None, proof=None): 76 106 RuntimeError.__init__(self) 77 107 self.desc = desc … … 79 109 else: self.code = -1 80 110 self.errstr = errstr 111 self.proof = proof 81 112 82 113 class CertificateMismatchError(RuntimeError): pass … … 98 129 ''' 99 130 rv = [ ] 100 if dir :131 if dir and os.path.isdir(dir): 101 132 for fn in ["%s/%s" % (dir, p) for p in os.listdir(dir) \ 102 133 if os.path.isfile("%s/%s" % (dir,p))]: … … 138 169 elif 'FEDD_URL' in os.environ: url = os.environ['FEDD_URL'] 139 170 else: url = default_url 171 172 if opts.abac_dir: 173 if not os.access(opts.abac_dir, os.F_OK): 174 raise RuntimeError("No ABAC directory: %s" % opts.abac_dir) 175 elif not os.path.isdir(opts.abac_dir): 176 raise RuntimeError("ABAC directory not a directory: %s" \ 177 % opts.abac_dir) 178 elif not os.access(opts.abac_dir, os.W_OK): 179 raise RuntimeError("Cannot write to ABAC directory: %s" \ 180 % opts.abac_dir) 181 140 182 141 183 … … 189 231 except service_error, e: 190 232 raise RPCException(desc=e.desc, code=e.code, 191 errstr=e.code_string() )233 errstr=e.code_string(), proof=e.proof) 192 234 elif transport == "xmlrpc": 193 235 if serialize_only: -
fedd/federation/deter_internal_access.py
rac15159 r0a49bd7 142 142 } 143 143 144 def RequestAccess(self, req, fid): 145 """ 146 Handle the access request. Proxy if not for us. 147 148 Parse out the fields and make the allocations or rejections if for us, 149 otherwise, assuming we're willing to proxy, proxy the request out. 150 """ 151 152 # The dance to get into the request body 153 if req.has_key('RequestAccessRequestBody'): 154 req = req['RequestAccessRequestBody'] 155 else: 156 raise service_error(service_error.req, "No request!?") 157 158 found, match, owners = self.lookup_access(req, fid) 159 # keep track of what's been added 160 allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log) 161 aid = unicode(allocID) 162 163 self.state_lock.acquire() 164 self.state[aid] = { } 165 self.state[aid]['user'] = found 166 self.state[aid]['owners'] = owners 167 self.state[aid]['vlan'] = None 168 self.write_state() 169 self.state_lock.release() 170 self.auth.set_attribute(fid, allocID) 171 self.auth.set_attribute(allocID, allocID) 172 self.auth.save() 173 174 try: 175 f = open("%s/%s.pem" % (self.certdir, aid), "w") 176 print >>f, alloc_cert 177 f.close() 178 except EnvironmentError, e: 179 raise service_error(service_error.internal, 180 "Can't open %s/%s : %s" % (self.certdir, aid, e)) 181 return { 'allocID': { 'fedid': allocID } } 182 183 def ReleaseAccess(self, req, fid): 184 # The dance to get into the request body 185 if req.has_key('ReleaseAccessRequestBody'): 186 req = req['ReleaseAccessRequestBody'] 187 else: 188 raise service_error(service_error.req, "No request!?") 189 190 # Local request 191 try: 192 if req['allocID'].has_key('localname'): 193 auth_attr = aid = req['allocID']['localname'] 194 elif req['allocID'].has_key('fedid'): 195 aid = unicode(req['allocID']['fedid']) 196 auth_attr = req['allocID']['fedid'] 197 else: 198 raise service_error(service_error.req, 199 "Only localnames and fedids are understood") 200 except KeyError: 201 raise service_error(service_error.req, "Badly formed request") 202 203 self.log.debug("[access] deallocation requested for %s", aid) 204 if not self.auth.check_attribute(fid, auth_attr): 205 self.log.debug("[access] deallocation denied for %s", aid) 206 raise service_error(service_error.access, "Access Denied") 207 208 self.state_lock.acquire() 209 if self.state.has_key(aid): 210 self.log.debug("Found allocation for %s" %aid) 211 del self.state[aid] 212 self.write_state() 213 self.state_lock.release() 214 # And remove the access cert 215 cf = "%s/%s.pem" % (self.certdir, aid) 216 self.log.debug("Removing %s" % cf) 217 os.remove(cf) 218 return { 'allocID': req['allocID'] } 219 else: 220 self.state_lock.release() 221 raise service_error(service_error.req, "No such allocation") 144 # RequestAccess and ReleaseAccess come from the base 222 145 223 146 def extract_parameters(self, top): … … 292 215 aid = "%s" % auth_attr 293 216 attrs = req.get('fedAttr', []) 294 if not self.auth.check_attribute(fid, auth_attr): 217 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 218 with_proof=True) 219 if not access_ok: 295 220 raise service_error(service_error.access, "Access denied") 296 221 else: … … 348 273 'allocID': req['allocID'], 349 274 'allocationLog': logv, 350 'segmentdescription': { 'topdldescription': rtopo.to_dict() } 275 'segmentdescription': { 'topdldescription': rtopo.to_dict() }, 276 'proof': proof.to_dict(), 351 277 } 352 278 retval = copy.deepcopy(self.state[aid]['started']) … … 366 292 367 293 self.log.debug("Terminate request for %s" %aid) 368 if not self.auth.check_attribute(fid, auth_attr): 294 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 295 with_proof=True) 296 if not access_ok: 369 297 raise service_error(service_error.access, "Access denied") 370 298 … … 385 313 self.state[aid]['vlan'] = None 386 314 self.state_lock.release() 387 return { 'allocID': req['allocID'] }315 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } -
fedd/federation/dragon_access.py
rac15159 r0a49bd7 122 122 else: raise self.parse_error("Repo should be in parens"); 123 123 124 def RequestAccess(self, req, fid): 125 """ 126 Handle the access request. 127 128 Parse out the fields and make the allocations or rejections if for us, 129 otherwise, assuming we're willing to proxy, proxy the request out. 130 """ 131 132 # The dance to get into the request body 133 if req.has_key('RequestAccessRequestBody'): 134 req = req['RequestAccessRequestBody'] 135 else: 136 raise service_error(service_error.req, "No request!?") 137 138 if req.has_key('destinationTestbed'): 139 dt = unpack_id(req['destinationTestbed']) 140 141 # Request for this fedd 142 found, match, owners = self.lookup_access(req, fid) 143 # keep track of what's been added 144 allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log) 145 aid = unicode(allocID) 146 147 self.state_lock.acquire() 148 self.state[aid] = { } 149 self.state[aid]['user'] = found 150 self.state[aid]['owners'] = owners 151 self.write_state() 152 self.state_lock.release() 153 self.auth.set_attribute(fid, allocID) 154 self.auth.set_attribute(allocID, allocID) 155 self.auth.save() 156 157 try: 158 f = open("%s/%s.pem" % (self.certdir, aid), "w") 159 print >>f, alloc_cert 160 f.close() 161 except EnvironmentError, e: 162 raise service_error(service_error.internal, 163 "Can't open %s/%s : %s" % (self.certdir, aid, e)) 164 return { 'allocID': { 'fedid': allocID } } 165 166 def ReleaseAccess(self, req, fid): 167 # The dance to get into the request body 168 if req.has_key('ReleaseAccessRequestBody'): 169 req = req['ReleaseAccessRequestBody'] 170 else: 171 raise service_error(service_error.req, "No request!?") 172 173 try: 174 if req['allocID'].has_key('localname'): 175 auth_attr = aid = req['allocID']['localname'] 176 elif req['allocID'].has_key('fedid'): 177 aid = unicode(req['allocID']['fedid']) 178 auth_attr = req['allocID']['fedid'] 179 else: 180 raise service_error(service_error.req, 181 "Only localnames and fedids are understood") 182 except KeyError: 183 raise service_error(service_error.req, "Badly formed request") 184 185 self.log.debug("[access] deallocation requested for %s", aid) 186 if not self.auth.check_attribute(fid, auth_attr): 187 self.log.debug("[access] deallocation denied for %s", aid) 188 raise service_error(service_error.access, "Access Denied") 189 190 self.state_lock.acquire() 191 if self.state.has_key(aid): 192 self.log.debug("Found allocation for %s" %aid) 193 del self.state[aid] 194 self.write_state() 195 self.state_lock.release() 196 # And remove the access cert 197 cf = "%s/%s.pem" % (self.certdir, aid) 198 self.log.debug("Removing %s" % cf) 199 os.remove(cf) 200 return { 'allocID': req['allocID'] } 201 else: 202 self.state_lock.release() 203 raise service_error(service_error.req, "No such allocation") 124 # RequestAccess and ReleaseAccess come from the base class 204 125 205 126 def extract_parameters(self, top): … … 497 418 return (repo, alloc_log) 498 419 499 def finalize_experiment(self, topo, vlan_no, gri, aid, alloc_id ):420 def finalize_experiment(self, topo, vlan_no, gri, aid, alloc_id, proof): 500 421 """ 501 422 Place the relevant information in the global state block, and prepare … … 521 442 'topdldescription': rtopo.to_dict() 522 443 }, 444 'proof': proof.to_dict(), 523 445 } 524 446 retval = copy.deepcopy(self.state[aid]['started']) … … 541 463 aid = "%s" % auth_attr 542 464 attrs = req.get('fedAttr', []) 543 if not self.auth.check_attribute(fid, auth_attr): 465 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 466 with_proof=True) 467 if not access_ok: 544 468 raise service_error(service_error.access, "Access denied") 545 469 else: … … 587 511 if gri: 588 512 return self.finalize_experiment(topo, vlan_no, gri, aid, 589 req['allocID'] )513 req['allocID'], proof) 590 514 elif err: 591 515 raise service_error(service_error.federant, … … 605 529 self.log.debug("Terminate request for %s" %aid) 606 530 attrs = req.get('fedAttr', []) 607 if not self.auth.check_attribute(fid, auth_attr): 531 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 532 with_proof=True) 533 if not access_ok: 608 534 raise service_error(service_error.access, "Access denied") 609 535 … … 628 554 self.log.debug("Stop segment for GRI: %s" %gri) 629 555 self.stop_segment(user, gri) 630 return { 'allocID': req['allocID'] }556 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } -
fedd/federation/emulab_access.py
rac15159 r0a49bd7 24 24 from service_error import service_error 25 25 from remote_service import xmlrpc_handler, soap_handler, service_caller 26 from proof import proof as access_proof 26 27 27 28 import httplib … … 254 255 'Bad mapping (unbalanced parens or more than 1 comma)') 255 256 256 257 257 # RequestAccess support routines 258 258 … … 384 384 self.state_lock.acquire() 385 385 self.allocation[aid] = { } 386 self.allocation[aid]['auth'] = set() 386 387 try: 387 388 pname = ap['project']['name']['localname'] … … 480 481 481 482 if self.auth_type == "legacy": 482 found, dyn, owners = self.legacy_lookup_access(req, fid) 483 found, dyn, owners= self.legacy_lookup_access(req, fid) 484 proof = access_proof("me", fid, "create") 483 485 elif self.auth_type == 'abac': 484 found, dyn, owners = self.lookup_access(req, fid, filter=pf)486 found, dyn, owners, proof = self.lookup_access(req, fid, filter=pf) 485 487 else: 486 488 raise service_error(service_error.internal, … … 511 513 for k, v in svc_state.items(): 512 514 self.allocation[aid][k] = v 515 self.append_allocation_authorization(aid, 516 set([(o, allocID) for o in owners]), state_attr='allocation') 513 517 self.write_state() 514 518 self.state_lock.release() 515 # Give the owners the right to change this allocation516 for o in owners:517 self.auth.set_attribute(o, allocID)518 self.auth.save()519 519 try: 520 520 f = open("%s/%s.pem" % (self.certdir, aid), "w") … … 525 525 "Can't open %s/%s : %s" % (self.certdir, aid, e)) 526 526 resp = self.build_access_response({ 'fedid': allocID } , 527 ap, services )527 ap, services, proof) 528 528 return resp 529 529 … … 572 572 self.log.debug("[access] deallocation requested for %s by %s" % \ 573 573 (aid, fid)) 574 if not self.auth.check_attribute(fid, auth_attr): 574 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 575 with_proof=True) 576 if not access_ok: 575 577 self.log.debug("[access] deallocation denied for %s", aid) 576 578 raise service_error(service_error.access, "Access Denied") … … 591 593 if aid in self.allocation: 592 594 self.log.debug("Found allocation for %s" %aid) 595 self.clear_allocation_authorization(aid, state_attr='allocation') 593 596 for k in self.allocation[aid]['keys']: 594 597 kk = "%s:%s" % k … … 625 628 self.log.debug("Removing %s" % cf) 626 629 os.remove(cf) 627 return { 'allocID': req['allocID'] }630 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } 628 631 else: 629 632 self.state_lock.release() … … 998 1001 return (ename, proj, user, pubkey_base, secretkey_base, alloc_log) 999 1002 1000 def finalize_experiment(self, starter, topo, aid, alloc_id ):1003 def finalize_experiment(self, starter, topo, aid, alloc_id, proof): 1001 1004 """ 1002 1005 Store key bits of experiment state in the global repository, including … … 1023 1026 'topdldescription': topo.clone().to_dict() 1024 1027 }, 1025 'embedding': embedding 1028 'embedding': embedding, 1029 'proof': proof.to_dict(), 1026 1030 } 1027 1031 retval = copy.copy(self.allocation[aid]['started']) … … 1047 1051 aid = "%s" % auth_attr 1048 1052 attrs = req.get('fedAttr', []) 1049 if not self.auth.check_attribute(fid, auth_attr): 1053 1054 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 1055 with_proof=True) 1056 if not access_ok: 1050 1057 raise service_error(service_error.access, "Access denied") 1051 1058 else: … … 1113 1120 1114 1121 if rv: 1115 return self.finalize_experiment(starter, topo, aid, req['allocID']) 1122 return self.finalize_experiment(starter, topo, aid, req['allocID'], 1123 proof) 1116 1124 elif err: 1117 1125 raise service_error(service_error.federant, … … 1129 1137 aid = "%s" % auth_attr 1130 1138 attrs = req.get('fedAttr', []) 1131 if not self.auth.check_attribute(fid, auth_attr): 1139 1140 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 1141 with_proof=True) 1142 if not access_ok: 1132 1143 raise service_error(service_error.access, "Access denied") 1133 1144 … … 1158 1169 debug=self.create_debug, boss=self.boss, cert=self.xmlrpc_cert) 1159 1170 stopper(self, user, proj, ename) 1160 return { 'allocID': req['allocID'] }1171 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } -
fedd/federation/experiment_control.py
rac15159 r0a49bd7 151 151 accessdb_file = config.get("experiment_control", "accessdb") 152 152 153 self.ssh_pubkey_file = config.get("experiment_control",154 "ssh_pubkey_file")155 self.ssh_privkey_file = config.get("experiment_control",156 "ssh_privkey_file")157 153 dt = config.get("experiment_control", "direct_transit") 158 154 self.auth_type = config.get('experiment_control', 'auth_type') \ … … 209 205 raise service_error(service_error.internal, 210 206 "Unknown auth_type: %s" % self.auth_type) 211 212 213 if self.ssh_pubkey_file:214 try:215 f = open(self.ssh_pubkey_file, 'r')216 self.ssh_pubkey = f.read()217 f.close()218 except EnvironmentError:219 raise service_error(service_error.internal,220 "Cannot read sshpubkey")221 else:222 raise service_error(service_error.internal,223 "No SSH public key file?")224 225 if not self.ssh_privkey_file:226 raise service_error(service_error.internal,227 "No SSH public key file?")228 229 207 230 208 if mapdb_file: … … 801 779 self.response = None 802 780 self.node = { } 781 self.proof = None 803 782 804 783 def make_map(self, resp): … … 850 829 self.log_collector.write(line) 851 830 self.make_map(r['StartSegmentResponseBody']) 831 if 'proof' in r: self.proof = r['proof'] 852 832 self.response = r 853 833 else: … … 1021 1001 # mapping. 1022 1002 embedding = [ ] 1003 proofs = { } 1023 1004 for s in starters: 1024 1005 for k, v in s.node.items(): … … 1028 1009 'testbed': s.testbed 1029 1010 }) 1011 if s.proof: 1012 proofs[s.testbed] = s.proof 1030 1013 log.info("[start_segment]: Experiment %s active" % eid) 1031 1014 … … 1044 1027 top.to_dict() 1045 1028 self.state[eid]['embedding'] = embedding 1029 # Append startup proofs 1030 for f in self.state[eid]['federant']: 1031 if 'name' in f and 'localname' in f['name']: 1032 if f['name']['localname'] in proofs: 1033 f['proof'].append(proofs[f['name']['localname']]) 1034 1046 1035 if self.state_filename: self.write_state() 1047 1036 self.state_lock.release() … … 1061 1050 if isinstance(e.software, list): e.software.extend(s) 1062 1051 else: e.software = s 1052 1053 def append_experiment_authorization(self, expid, attrs, 1054 need_state_lock=True): 1055 """ 1056 Append the authorization information to system state 1057 """ 1058 1059 for p, a in attrs: 1060 self.auth.set_attribute(p, a) 1061 self.auth.save() 1062 1063 if need_state_lock: self.state_lock.acquire() 1064 self.state[expid]['auth'].update(attrs) 1065 if self.state_filename: self.write_state() 1066 if need_state_lock: self.state_lock.release() 1067 1068 def clear_experiment_authorization(self, expid, need_state_lock=True): 1069 """ 1070 Attrs is a set of attribute principal pairs that need to be removed 1071 from the authenticator. Remove them and save the authenticator. 1072 """ 1073 1074 if need_state_lock: self.state_lock.acquire() 1075 if expid in self.state and 'auth' in self.state[expid]: 1076 for p, a in self.state[expid]['auth']: 1077 self.auth.unset_attribute(p, a) 1078 self.state[expid]['auth'] = set() 1079 if self.state_filename: self.write_state() 1080 if need_state_lock: self.state_lock.release() 1081 self.auth.save() 1063 1082 1064 1083 … … 1087 1106 status = self.state[eid].get('experimentStatus', None) 1088 1107 if status and status == 'failed': 1089 # remove the old access attribute 1090 self. auth.unset_attribute(fid, old_expid)1091 self.auth.save()1108 # remove the old access attributes 1109 self.clear_experiment_authorization(eid, 1110 need_state_lock=False) 1092 1111 overwrite = True 1093 1112 del self.state[eid] … … 1105 1124 'owner': fid, 1106 1125 'log' : [], 1126 'auth': set(), 1107 1127 } 1108 1128 self.state[expid] = self.state[eid] 1109 1110 1129 if self.state_filename: self.write_state() 1130 self.state_lock.release() 1111 1131 else: 1112 1132 eid = self.exp_stem … … 1126 1146 'owner': fid, 1127 1147 'log' : [], 1148 'auth': set(), 1128 1149 } 1129 1150 self.state[expid] = self.state[eid] 1130 if self.state_filename: self.write_state() 1131 self.state_lock.release() 1151 if self.state_filename: self.write_state() 1152 self.state_lock.release() 1153 1154 # Let users touch the state. Authorize this fid and the expid itself 1155 # to touch the experiment, as well as allowing th eoverrides. 1156 self.append_experiment_authorization(eid, 1157 set([(fid, expid), (expid,expid)] + \ 1158 [ (o, expid) for o in self.overrides])) 1132 1159 1133 1160 return eid … … 1288 1315 raise service_error(service_error.protocol, 1289 1316 "Bad proxy response") 1317 if 'proof' not in r: 1318 raise service_error(service_error.protocol, 1319 "Bad access response (no access proof)") 1290 1320 1291 1321 tbparam[tb] = { 1292 1322 "allocID" : r['allocID'], 1293 1323 "uri": uri, 1324 "proof": [ r['proof'] ], 1294 1325 } 1295 1326 … … 1337 1368 topo[tb].make_indices() 1338 1369 1370 def confirm_software(self, top): 1371 """ 1372 Make sure that the software to be loaded in the topo is all available 1373 before we begin making access requests, etc. This is a subset of 1374 wrangle_software. 1375 """ 1376 pkgs = set([ d for i, d in self.fedkit + self.gatewaykit ]) 1377 pkgs.update([x.location for e in top.elements for x in e.software]) 1378 1379 for pkg in pkgs: 1380 loc = pkg 1381 1382 scheme, host, path = urlparse(loc)[0:3] 1383 dest = os.path.basename(path) 1384 if not scheme: 1385 if not loc.startswith('/'): 1386 loc = "/%s" % loc 1387 loc = "file://%s" %loc 1388 # NB: if scheme was found, loc == pkg 1389 try: 1390 u = urlopen(loc) 1391 u.close() 1392 except Exception, e: 1393 raise service_error(service_error.req, 1394 "Cannot open %s: %s" % (loc, e)) 1395 return True 1396 1339 1397 def wrangle_software(self, expid, top, topo, tbparams): 1340 1398 """ … … 1349 1407 softdir ="%s/%s" % ( self.repodir, linkpath) 1350 1408 softmap = { } 1351 # These are in a list of tuples format (each kit). This comprehension 1352 # unwraps them into a single list of tuples that initilaizes the set of 1353 # tuples. 1354 pkgs = set([ t for l in [self.fedkit, self.gatewaykit] \ 1355 for p, t in l ]) 1356 pkgs.update([x.location for e in top.elements \ 1357 for x in e.software]) 1409 1410 # self.fedkit and self.gateway kit are lists of tuples of 1411 # (install_location, download_location) this extracts the download 1412 # locations. 1413 pkgs = set([ d for i, d in self.fedkit + self.gatewaykit ]) 1414 pkgs.update([x.location for e in top.elements for x in e.software]) 1358 1415 try: 1359 1416 os.makedirs(softdir) … … 1362 1419 "Cannot create software directory: %s" % e) 1363 1420 # The actual copying. Everything's converted into a url for copying. 1421 auth_attrs = set() 1364 1422 for pkg in pkgs: 1365 1423 loc = pkg … … 1371 1429 loc = "/%s" % loc 1372 1430 loc = "file://%s" %loc 1431 # NB: if scheme was found, loc == pkg 1373 1432 try: 1374 1433 u = urlopen(loc) … … 1394 1453 ( self.repo_url, path, dest) 1395 1454 1396 # Allow the individual segments to access the software. 1397 for tb in tbparams.keys(): 1398 self.auth.set_attribute(tbparams[tb]['allocID']['fedid'], 1399 "/%s/%s" % ( path, dest)) 1400 self.auth.save() 1455 # Allow the individual segments to access the software by assigning 1456 # an attribute to each testbed allocation that encodes the data to 1457 # be released. This expression collects the data for each run of 1458 # the loop. 1459 auth_attrs.update([ 1460 (tbparams[tb]['allocID']['fedid'], "/%s/%s" % ( path, dest)) \ 1461 for tb in tbparams.keys()]) 1462 1463 self.append_experiment_authorization(expid, auth_attrs) 1401 1464 1402 1465 # Convert the software locations in the segments into the local … … 1428 1491 self.auth.save() 1429 1492 1430 if not self.auth.check_attribute(fid, 'new'): 1431 raise service_error(service_error.access, "New access denied") 1493 access_ok, proof = self.auth.check_attribute(fid, 'new', 1494 with_proof=True) 1495 1496 if not access_ok: 1497 raise service_error(service_error.access, "New access denied", 1498 proof=[proof]) 1432 1499 1433 1500 try: … … 1468 1535 state='empty') 1469 1536 1470 # Let users touch the state1471 self.auth.set_attribute(fid, expid)1472 self.auth.set_attribute(expid, expid)1473 # Override fedids can manipulate state as well1474 for o in self.overrides:1475 self.auth.set_attribute(o, expid)1476 self.auth.save()1477 1478 1537 rv = { 1479 1538 'experimentID': [ … … 1481 1540 ], 1482 1541 'experimentStatus': 'empty', 1483 'experimentAccess': { 'X509' : expcert } 1542 'experimentAccess': { 'X509' : expcert }, 1543 'proof': proof.to_dict(), 1484 1544 } 1485 1545 … … 1609 1669 return top 1610 1670 1611 def get_testbed_services(self, req ):1671 def get_testbed_services(self, req, testbeds): 1612 1672 """ 1613 1673 Parse the services section of the request into into two dicts mapping … … 1700 1760 "Cannot copy keyfiles: %s" % e) 1701 1761 1702 # Allow the individual testbeds to access the configuration files .1703 for tb in tbparams.keys():1704 asignee = tbparams[tb]['allocID']['fedid']1705 for f in ("hosts", gw_secretkey_base, gw_pubkey_base):1706 self.auth.set_attribute(asignee, "%s/%s" %\1707 (configpath, f))1708 self.auth.save()1762 # Allow the individual testbeds to access the configuration files, 1763 # again by setting an attribute for the relevant pathnames on each 1764 # allocation principal. Yeah, that's a long list comprehension. 1765 self.append_experiment_authorization(expid, set([ 1766 (tbparams[tb]['allocID']['fedid'], "%s/%s" % (configpath, f)) \ 1767 for tb in tbparams.keys() \ 1768 for f in ("hosts", gw_secretkey_base, gw_pubkey_base)])) 1709 1769 1710 1770 attrs = [ … … 1752 1812 raise service_error(service_error.req, "No request?") 1753 1813 1754 self.check_experiment_access(fid, key)1814 proof = self.check_experiment_access(fid, key) 1755 1815 1756 1816 self.state_lock.acquire() 1757 1817 if self.state.has_key(key): 1758 1818 if self.state[key].has_key('vtopo'): 1759 rv = { 'experiment' : {keytype: key },\ 1760 'vtopo': self.state[key]['vtopo'],\ 1819 rv = { 'experiment' : {keytype: key }, 1820 'vtopo': self.state[key]['vtopo'], 1821 'proof': proof.to_dict(), 1761 1822 } 1762 1823 else: … … 1796 1857 raise service_error(service_error.req, "No request?") 1797 1858 1798 self.check_experiment_access(fid, key)1859 proof = self.check_experiment_access(fid, key) 1799 1860 1800 1861 self.state_lock.acquire() 1801 1862 if self.state.has_key(key): 1802 1863 if self.state[key].has_key('vis'): 1803 rv = { 'experiment' : {keytype: key },\ 1804 'vis': self.state[key]['vis'],\ 1864 rv = { 'experiment' : {keytype: key }, 1865 'vis': self.state[key]['vis'], 1866 'proof': proof.to_dict(), 1805 1867 } 1806 1868 else: … … 1823 1885 between when it was started and the beginning of resource allocation. 1824 1886 This is basically the information about each local allocation. This 1825 fills in the values of the placeholder allocation in the state. 1887 fills in the values of the placeholder allocation in the state. It 1888 also collects the access proofs and returns them as dicts for a 1889 response message. 1826 1890 """ 1827 1891 # save federant information … … 1831 1895 'allocID' : tbparams[k]['allocID'], 1832 1896 'uri': tbparams[k]['uri'], 1897 'proof': tbparams[k]['proof'], 1833 1898 } 1834 1899 … … 1841 1906 [ tbparams[tb]['federant'] for tb in tbparams.keys() \ 1842 1907 if tbparams[tb].has_key('federant') ] 1908 # Access proofs for the response message 1909 proofs = [copy.deepcopy(p) for k in tbparams.keys()\ 1910 for p in tbparams[k]['federant']['proof']] 1843 1911 if self.state_filename: 1844 1912 self.write_state() 1845 1913 self.state_lock.release() 1914 return proofs 1846 1915 1847 1916 def clear_placeholder(self, eid, expid, tmpdir): … … 1883 1952 1884 1953 # Make sure that the caller can talk to us 1885 self.check_experiment_access(fid, key)1954 proof = self.check_experiment_access(fid, key) 1886 1955 1887 1956 # Install the testbed map entries supplied with the request into a copy … … 1911 1980 1912 1981 top = self.get_topology(req, tmpdir) 1982 self.confirm_software(top) 1913 1983 # Assign the IPs 1914 1984 hosts, ip_allocator = self.allocate_ips_to_topo(top) … … 1924 1994 testbeds.append(tb) 1925 1995 1926 masters, pmasters = self.get_testbed_services(req )1996 masters, pmasters = self.get_testbed_services(req, testbeds) 1927 1997 allocated = { } # Testbeds we can access 1928 1998 topo ={ } # Sub topologies 1929 1999 connInfo = { } # Connection information 1930 2000 2001 self.split_topology(top, topo, testbeds) 2002 1931 2003 self.get_access_to_testbeds(testbeds, fid, allocated, 1932 2004 tbparams, masters, tbmap, expid, expcert_file) 1933 1934 self.split_topology(top, topo, testbeds)1935 2005 1936 2006 attrs = self.generate_keys_and_hosts(tmpdir, expid, hosts, tbparams) … … 1940 2010 part.add_portals(top, topo, eid, pmasters, tbparams, ip_allocator, 1941 2011 connInfo, expid) 2012 2013 auth_attrs = set() 1942 2014 # Now get access to the dynamic testbeds (those added above) 1943 2015 for tb in [ t for t in topo if t not in allocated]: … … 1948 2020 # Give the testbed access to keys it exports or imports 1949 2021 if store_keys: 1950 for sk in store_keys.split(" "): 1951 self.auth.set_attribute(\ 1952 tbparams[tb]['allocID']['fedid'], sk) 1953 self.auth.save() 2022 auth_attrs.update(set([ 2023 (tbparams[tb]['allocID']['fedid'], sk) \ 2024 for sk in store_keys.split(" ")])) 2025 2026 if auth_attrs: 2027 self.append_experiment_authorization(expid, auth_attrs) 1954 2028 1955 2029 # transit and disconnected testbeds may not have a connInfo entry. … … 1963 2037 vtopo = topdl.topology_to_vtopo(top) 1964 2038 vis = self.genviz(vtopo) 1965 self.save_federant_information(allocated, tbparams, eid, vtopo,1966 vis, top)2039 proofs = self.save_federant_information(allocated, tbparams, 2040 eid, vtopo, vis, top) 1967 2041 except service_error, e: 1968 2042 # If something goes wrong in the parse (usually an access error) … … 1975 2049 # Start the background swapper and return the starting state. From 1976 2050 # here on out, the state will stick around a while. 1977 1978 # Let users touch the state1979 self.auth.set_attribute(fid, expid)1980 self.auth.set_attribute(expid, expid)1981 # Override fedids can manipulate state as well1982 for o in self.overrides:1983 self.auth.set_attribute(o, expid)1984 self.auth.save()1985 2051 1986 2052 # Create a logger that logs to the experiment's state object as well as … … 2008 2074 ], 2009 2075 'experimentStatus': 'starting', 2076 'proof': [ proof.to_dict() ] + proofs, 2010 2077 } 2011 2078 … … 2053 2120 key = self.get_experiment_fedid(key) 2054 2121 2055 if self.auth.check_attribute(fid, key): 2056 return True 2122 access_ok, proof = self.auth.check_attribute(fid, key, with_proof=True) 2123 2124 if access_ok: 2125 return proof 2057 2126 else: 2058 raise service_error(service_error.access, "Access Denied") 2127 raise service_error(service_error.access, "Access Denied", 2128 proof) 2059 2129 2060 2130 … … 2065 2135 """ 2066 2136 self.log.info("Get handler %s %s" % (path, fid)) 2137 # XXX: log proofs? 2067 2138 if self.auth.check_attribute(fid, path): 2068 2139 return ("%s/%s" % (self.repodir, path), "application/binary") … … 2070 2141 return (None, None) 2071 2142 2072 def clean_info_response(self, rv ):2143 def clean_info_response(self, rv, proof): 2073 2144 """ 2074 2145 Remove the information in the experiment's state object that is not in … … 2077 2148 # Remove the owner info (should always be there, but...) 2078 2149 if rv.has_key('owner'): del rv['owner'] 2150 if 'auth' in rv: del rv['auth'] 2079 2151 2080 2152 # Convert the log into the allocationLog parameter and remove the … … 2093 2165 if f.has_key('allocID'): del f['allocID'] 2094 2166 if f.has_key('uri'): del f['uri'] 2167 rv['proof'] = proof.to_dict() 2095 2168 2096 2169 return rv … … 2119 2192 raise service_error(service_error.req, "No request?") 2120 2193 2121 self.check_experiment_access(fid, key)2194 proof = self.check_experiment_access(fid, key) 2122 2195 2123 2196 # The state may be massaged by the service function that called … … 2130 2203 2131 2204 if rv: 2132 return self.clean_info_response(rv )2205 return self.clean_info_response(rv, proof) 2133 2206 else: 2134 2207 raise service_error(service_error.req, "No such experiment") … … 2138 2211 Return all the stored info that this fedid can access 2139 2212 """ 2140 rv = { 'info': [ ] }2213 rv = { 'info': [ ], 'proof': [ ] } 2141 2214 2142 2215 self.state_lock.acquire() 2143 2216 for key in [ k for k in self.state.keys() if isinstance(k, fedid)]: 2144 2217 try: 2145 self.check_experiment_access(fid, key)2218 proof = self.check_experiment_access(fid, key) 2146 2219 except service_error, e: 2147 2220 if e.code == service_error.access: … … 2153 2226 if self.state.has_key(key): 2154 2227 e = copy.deepcopy(self.state[key]) 2155 e = self.clean_info_response(e )2228 e = self.clean_info_response(e, proof) 2156 2229 rv['info'].append(e) 2230 rv['proof'].append(proof.to_dict()) 2157 2231 self.state_lock.release() 2158 2232 return rv … … 2282 2356 if tmpdir: self.remove_dirs(tmpdir) 2283 2357 2284 2285 2358 def terminate_experiment(self, req, fid): 2286 2359 """ … … 2295 2368 2296 2369 key = self.get_experiment_key(req, 'experiment') 2297 self.check_experiment_access(fid, key)2370 proof = self.check_experiment_access(fid, key) 2298 2371 exp = req.get('experiment', False) 2299 2372 force = req.get('force', False) … … 2326 2399 self.state_lock.acquire() 2327 2400 for id in ids: 2401 self.clear_experiment_authorization(id, need_state_lock=False) 2328 2402 if id in self.state: del self.state[id] 2329 2403 … … 2346 2420 if repo: 2347 2421 self.remove_dirs("%s/%s" % (self.repodir, repo)) 2348 2422 2349 2423 return { 2350 2424 'experiment': exp , 2351 2425 'deallocationLog': string.join(dealloc_list, ''), 2426 'proof': [proof.to_dict()], 2352 2427 } 2353 2428 else: … … 2368 2443 rv = { 'name': name } 2369 2444 2370 if name and self.auth.check_attribute(fid, name): 2445 if not name: 2446 raise service_error(service_error.req, "No name?") 2447 2448 access_ok, proof = self.auth.check_attribute(fid, name, with_proof=True) 2449 2450 if access_ok: 2371 2451 self.log.debug("[GetValue] asking for %s " % name) 2372 2452 try: … … 2378 2458 if v is not None: 2379 2459 rv['value'] = v 2460 rv['proof'] = proof.to_dict() 2380 2461 self.log.debug("[GetValue] got %s from %s" % (v, name)) 2381 2462 return rv 2382 2463 else: 2383 raise service_error(service_error.access, "Access Denied") 2464 raise service_error(service_error.access, "Access Denied", 2465 proof=proof) 2384 2466 2385 2467 … … 2396 2478 v = req.get('value', '') 2397 2479 2398 if name and self.auth.check_attribute(fid, name): 2480 if not name: 2481 raise service_error(service_error.req, "No name?") 2482 2483 access_ok, proof = self.auth.check_attribute(fid, name, with_proof=True) 2484 2485 if access_ok: 2399 2486 try: 2400 2487 self.synch_store.set_value(name, v) … … 2409 2496 raise service_error(service_error.federant, 2410 2497 "Synch key %s revoked" % name) 2411 return { 'name': name, 'value': v}2498 return { 'name': name, 'value': v, 'proof': proof.to_dict() } 2412 2499 else: 2413 raise service_error(service_error.access, "Access Denied") 2500 raise service_error(service_error.access, "Access Denied", 2501 proof=proof) -
fedd/federation/ns2topdl.py
rac15159 r0a49bd7 11 11 from remote_service import xmlrpc_handler, soap_handler 12 12 from service_error import * 13 from authorizer import authorizer 13 from authorizer import authorizer, abac_authorizer 14 14 15 15 … … 31 31 self.tcl_splitter = config.get("ns2topdl", "tcl_splitter", 32 32 "/usr/testbed/lib/ns2ir/parse.tcl") 33 self.auth_type = config.get('ns2topdl', 'auth_type') or 'legacy' 33 34 access_db = config.get("ns2topdl", "accessdb", None) 34 allow_any = config.getboolean("ns2topdl", "allow_any", False) 35 self.allow_any = config.getboolean("ns2topdl", "allow_any", False) 36 auth_dir = config.get('ns2topdl', 'auth_dir') 35 37 36 38 self.log = logging.getLogger("fedd.ns2topdl") … … 47 49 "using local one") 48 50 49 if access_db and allow_any: 51 52 if self.auth_type == 'legacy': 53 if access_db and self.allow_any: 54 raise service_error(service_error.internal, 55 "Cannot specify both an access database and " + 56 "allow_any for ns2topdl") 57 58 if access_db: 59 try: 60 read_simple_accessdb(access_db, self.auth, 'ns2topdl') 61 except EnvironmentError, e: 62 raise service_error(service_error.internal, 63 "Error reading accessDB %s: %s" % (access_db, e)) 64 except ValueError: 65 raise service_error(service_error.internal, "%s" % e) 66 elif self.allow_any: 67 auth.set_global_attribute("ns2topdl") 68 elif self.auth_type == 'abac': 69 self.auth = abac_authorizer(load=auth_dir) 70 else: 50 71 raise service_error(service_error.internal, 51 "Cannot specify both an access database and allow_any " +\ 52 "for ns2topdl") 53 54 if access_db: 55 try: 56 read_simple_accessdb(access_db, self.auth, 'ns2topdl') 57 except EnvironmentError, e: 58 raise service_error(service_error.internal, 59 "Error reading accessDB %s: %s" % (access_db, e)) 60 except ValueError: 61 raise service_error(service_error.internal, "%s" % e) 62 elif allow_any: 63 auth.set_global_attribute("ns2topdl") 72 "Unknown auth_type: %s" % self.auth_type) 64 73 65 74 … … 81 90 """ 82 91 83 if not self.auth.check_attribute(fid, 'ns2topdl'): 84 raise service_error(service_error.access, "Access Denied") 92 if self.allow_any: 93 self.auth.set_attribute(fid, 'ns2topdl') 94 95 access_ok, proof = self.auth.check_attribute(fid, 'ns2topdl', 96 with_proof=True) 97 98 if not access_ok: 99 raise service_error(service_error.access, "Access Denied", 100 proof=proof) 85 101 86 102 try: … … 137 153 'experimentdescription': { 138 154 'topdldescription': top.to_dict(), 139 } 155 }, 156 'proof': proof.to_dict(), 140 157 } 141 158 -
fedd/federation/parse_detail.py
rac15159 r0a49bd7 1 1 #!/usr/local/bin/python 2 2 3 from fedd_client import * 3 try: 4 from fedd_services import * 5 except ImportError: 6 from fedd_client import * 4 7 5 8 from ZSI.TC import QName, String, URI, AnyElement, UNBOUNDED, Any -
fedd/federation/protogeni_access.py
rac15159 r0a49bd7 215 215 return (None, None) 216 216 217 def build_access_response(self, alloc_id, services ):217 def build_access_response(self, alloc_id, services, proof): 218 218 """ 219 219 Create the SOAP response. … … 230 230 'fedAttr': [ 231 231 { 'attribute': 'domain', 'value': self.domain } , 232 ] 232 ], 233 'proof': proof.to_dict() 233 234 } 234 235 if self.dragon_endpoint: … … 262 263 263 264 # Request for this fedd 264 found, match, owners = self.lookup_access(req, fid)265 found, match, owners, proof = self.lookup_access(req, fid) 265 266 services, svc_state = self.export_services(req.get('service',[]), 266 267 None, None) … … 275 276 # The list of owner FIDs 276 277 self.allocation[aid]['owners'] = owners 278 self.allocation[aid]['auth'] = set() 279 self.append_allocation_authorization(aid, 280 ((fid, allocID), (allocID, allocID)), state_attr='allocation') 277 281 self.write_state() 278 282 self.state_lock.release() 279 self.auth.set_attribute(fid, allocID)280 self.auth.set_attribute(allocID, allocID)281 self.auth.save()282 283 283 284 try: … … 288 289 raise service_error(service_error.internal, 289 290 "Can't open %s/%s : %s" % (self.certdir, aid, e)) 290 return self.build_access_response({ 'fedid': allocID }, None )291 return self.build_access_response({ 'fedid': allocID }, None, proof) 291 292 292 293 … … 312 313 313 314 self.log.debug("[access] deallocation requested for %s", aid) 314 if not self.auth.check_attribute(fid, auth_attr): 315 access_ok , proof = self.auth.check_attribute(fid, auth_attr, 316 with_proof=True) 317 if not access_ok: 315 318 self.log.debug("[access] deallocation denied for %s", aid) 316 319 raise service_error(service_error.access, "Access Denied") … … 319 322 if self.allocation.has_key(aid): 320 323 self.log.debug("Found allocation for %s" %aid) 324 self.clear_allocation_authorization(aid, state_attr='allocation') 321 325 del self.allocation[aid] 322 326 self.write_state() … … 326 330 self.log.debug("Removing %s" % cf) 327 331 os.remove(cf) 328 return { 'allocID': req['allocID'] }332 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } 329 333 else: 330 334 self.state_lock.release() … … 1250 1254 cpw, alloc_log) 1251 1255 1252 def finalize_experiment(self, topo, nodes, aid, alloc_id ):1256 def finalize_experiment(self, topo, nodes, aid, alloc_id, proof): 1253 1257 # Copy the assigned names into the return topology 1254 1258 rvtopo = topo.clone() … … 1272 1276 'topdldescription': rvtopo.to_dict() }, 1273 1277 'embedding': embedding, 1278 'proof': proof.to_dict(), 1274 1279 } 1275 1280 retval = copy.deepcopy(self.allocation[aid]['started']) … … 1294 1299 aid = "%s" % auth_attr 1295 1300 attrs = req.get('fedAttr', []) 1296 if not self.auth.check_attribute(fid, auth_attr): 1301 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 1302 with_proof=True) 1303 if not access_ok: 1297 1304 raise service_error(service_error.access, "Access denied") 1298 1305 else: … … 1355 1362 1356 1363 if rv: 1357 return self.finalize_experiment(topo, nodes, aid, req['allocID']) 1364 return self.finalize_experiment(topo, nodes, aid, req['allocID'], 1365 proof) 1358 1366 elif err: 1359 1367 raise service_error(service_error.federant, … … 1391 1399 aid = "%s" % auth_attr 1392 1400 attrs = req.get('fedAttr', []) 1393 if not self.auth.check_attribute(fid, auth_attr): 1401 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 1402 with_proof=True) 1403 if not access_ok: 1394 1404 raise service_error(service_error.access, "Access denied") 1395 1405 … … 1418 1428 self.stop_segment(segment_commands, user, staging, slice_cred, 1419 1429 slice_urn, cf, cpw) 1420 return { 'allocID': req['allocID'] }1430 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } 1421 1431 1422 1432 def renew_segment(self, segment_commands, name, scred, slice_urn, interval, -
fedd/federation/remote_service.py
rac15159 r0a49bd7 16 16 import httplib 17 17 18 from proof import proof 18 19 from service_error import service_error 19 20 from xmlrpclib import ServerProxy, dumps, loads, Fault, Error, Binary … … 21 22 import fedd_services 22 23 import fedd_internal_services 24 service_port_name = 'getfeddPortType' 25 internal_service_port_name = 'getfeddInternalPortType' 23 26 except ImportError: 24 import fedd_server25 27 import fedd_client 28 import fedd_internal_client 29 fedd_services = fedd_client 30 fedd_internal_services = fedd_internal_client 31 service_port_name = 'getfeddPort' 32 internal_service_port_name = 'getfedd_internalPort' 26 33 27 34 from util import fedd_ssl_context … … 60 67 # A map used to encapsulate fedids into xmlrpclib.Binary objects 61 68 encap_fedids = (('fedid', to_binary),) 69 70 # fields that are never unicoded, because they represent non strings. 71 do_not_unicode = set(['credential']) 62 72 63 73 @staticmethod … … 166 176 if isinstance(obj, dict): 167 177 for k in obj.keys(): 168 obj[k] = remote_service_base.make_unicode(obj[k]) 178 if k not in remote_service_base.do_not_unicode: 179 obj[k] = remote_service_base.make_unicode(obj[k]) 169 180 return obj 170 181 elif isinstance(obj, basestring) and not isinstance(obj, unicode): … … 283 294 self.service_name = service_name 284 295 296 <<<<<<< HEAD 285 297 try: 286 298 if getattr(fedd_services.feddBindingSOAP, service_name, None): … … 300 312 self.port_name = 'getfedd_internalPort' 301 313 314 ======= 315 if getattr(fedd_services.feddBindingSOAP, service_name, None): 316 self.locator = fedd_services.feddServiceLocator 317 self.port_name = service_port_name 318 elif getattr(fedd_internal_services.feddInternalBindingSOAP, 319 service_name, None): 320 self.locator = fedd_internal_services.feddInternalServiceLocator 321 self.port_name = internal_service_port_name 322 >>>>>>> 944b746d2f97c5803ca28f587dd7100a57e25a69 302 323 303 324 if request_message: self.request_message = request_message 304 325 else: 305 326 request_message_name = "%sRequestMessage" % service_name 327 <<<<<<< HEAD 306 328 try: 307 329 self.request_message = \ … … 314 336 getattr(fedd_internal_client, request_message_name, 315 337 None) 338 ======= 339 self.request_message = \ 340 getattr(fedd_services, request_message_name, None) or \ 341 getattr(fedd_internal_services, request_message_name, 342 None) 343 >>>>>>> 944b746d2f97c5803ca28f587dd7100a57e25a69 316 344 if not self.request_message and strict: 317 345 raise service_error(service_error.internal, … … 523 551 'desc': e.fault.string or "Something Weird" } 524 552 if ee: 553 if 'proof' in ee: 554 pl = [ proof.from_dict(p) for p in ee['proof']] 555 else: 556 pl = None 525 557 raise service_error(ee.get('code', 'no code'), 526 ee.get('desc','no desc') )558 ee.get('desc','no desc'), proof=pl) 527 559 else: 528 560 raise service_error(service_error.internal, -
fedd/federation/server.py
rac15159 r0a49bd7 13 13 14 14 from fedid import fedid 15 from fedd_services import ns0 15 16 # ZSI uses a deprecated multifile interface. This shuts the warning system up. 17 from warnings import filterwarnings 18 filterwarnings("ignore", ".*multifile.*", DeprecationWarning, "ZSI") 19 20 try: 21 from fedd_services import ns0 22 except ImportError: 23 from fedd_server import ns0 24 16 25 from service_error import * 17 26 … … 127 136 self.send_fault(f) 128 137 resp = None 129 138 130 139 if resp != None: 131 140 sw = SoapWriter() … … 192 201 de._errstr=e.code_string() 193 202 de._desc=e.desc 203 for p in e.proof: 204 dp = ns0.proofType_Def(ns0.proofType_Def.schema, 205 "proof").pyclass() 206 dp._prover = p.prover 207 dp._principal = p.principal 208 dp._attribute = p.attribute 209 dp._credential = p.creds_to_certs() 210 if de._proof: de._proof.append(dp) 211 else: de._proof = [dp] 194 212 if e.is_server_error(): 195 213 raise Fault(Fault.Server, e.code_string(), detail=de) -
fedd/federation/service_error.py
rac15159 r0a49bd7 28 28 federant, connect) 29 29 30 def __init__(self, code=None, desc=None, from_string=None ):30 def __init__(self, code=None, desc=None, from_string=None, proof=None): 31 31 self.code = code 32 32 self.desc = desc 33 self.proof = proof or [] 34 if not isinstance (self.proof, list): self.proof = [ proof ] 33 35 if code == None: 34 36 self.set_code_from_string(from_string) -
fedd/federation/skeleton_access.py
rac15159 r0a49bd7 163 163 } 164 164 165 def RequestAccess(self, req, fid): 166 """ 167 Handle an access request. Success here maps the requester into the 168 local access control space and establishes state about that user keyed 169 to a fedid. We also save a copy of the certificate underlying that 170 fedid so this allocation can access configuration information and 171 shared parameters on the experiment controller. 172 """ 173 174 # The dance to get into the request body 175 if req.has_key('RequestAccessRequestBody'): 176 req = req['RequestAccessRequestBody'] 177 else: 178 raise service_error(service_error.req, "No request!?") 179 180 # Base class lookup routine. If this fails, it throws a service 181 # exception denying access that triggers a fault response back to the 182 # caller. 183 found, match, owners = self.lookup_access(req, fid) 184 self.log.info( 185 "[RequestAccess] Access granted to %s with local creds %s" % \ 186 (match, found)) 187 # Make a fedid for this allocation 188 allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log) 189 aid = unicode(allocID) 190 191 # Store the data about this allocation: 192 self.state_lock.acquire() 193 self.state[aid] = { } 194 self.state[aid]['user'] = found 195 self.state[aid]['owners'] = owners 196 self.write_state() 197 self.state_lock.release() 198 # Authorize the creating fedid and the principal representing the 199 # allocation to manipulate it. 200 self.auth.set_attribute(fid, allocID) 201 self.auth.set_attribute(allocID, allocID) 202 self.auth.save() 203 204 # Create a directory to stash the certificate in, ans stash it. 205 try: 206 f = open("%s/%s.pem" % (self.certdir, aid), "w") 207 print >>f, alloc_cert 208 f.close() 209 except EnvironmentError, e: 210 raise service_error(service_error.internal, 211 "Can't open %s/%s : %s" % (self.certdir, aid, e)) 212 self.log.debug('[RequestAccess] Returning allocation ID: %s' % allocID) 213 return { 'allocID': { 'fedid': allocID } } 214 215 def ReleaseAccess(self, req, fid): 216 """ 217 Release the allocation granted earlier. Access to the allocation is 218 checked and if valid, the state and cached certificate are destroyed. 219 """ 220 # The dance to get into the request body 221 if req.has_key('ReleaseAccessRequestBody'): 222 req = req['ReleaseAccessRequestBody'] 223 else: 224 raise service_error(service_error.req, "No request!?") 225 226 # Pull a key out of the request. One can request to delete an 227 # allocation by a local human readable name or by a fedid. This finds 228 # both choices. 229 try: 230 if 'localname' in req['allocID']: 231 auth_attr = aid = req['allocID']['localname'] 232 elif 'fedid' in req['allocID']: 233 aid = unicode(req['allocID']['fedid']) 234 auth_attr = req['allocID']['fedid'] 235 else: 236 raise service_error(service_error.req, 237 "Only localnames and fedids are understood") 238 except KeyError: 239 raise service_error(service_error.req, "Badly formed request") 240 241 self.log.debug("[ReleaseAccess] deallocation requested for %s", aid) 242 # Confirm access 243 if not self.auth.check_attribute(fid, auth_attr): 244 self.log.debug("[ReleaseAccess] deallocation denied for %s", aid) 245 raise service_error(service_error.access, "Access Denied") 246 247 # If there is an allocation in the state, delete it. Note the locking. 248 self.state_lock.acquire() 249 if aid in self.state: 250 self.log.debug("[ReleaseAccess] Found allocation for %s" %aid) 251 del self.state[aid] 252 self.write_state() 253 self.state_lock.release() 254 # And remove the access cert 255 cf = "%s/%s.pem" % (self.certdir, aid) 256 self.log.debug("[ReleaseAccess] Removing %s" % cf) 257 os.remove(cf) 258 return { 'allocID': req['allocID'] } 259 else: 260 self.state_lock.release() 261 raise service_error(service_error.req, "No such allocation") 165 # RequestAccess and ReleaseAccess come from the base class 262 166 263 167 def StartSegment(self, req, fid): … … 279 183 aid = "%s" % auth_attr 280 184 # Authorization check 281 if not self.auth.check_attribute(fid, auth_attr): 282 raise service_error(service_error.access, "Access denied") 185 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 186 with_proof=True) 187 if not access_ok: 188 raise service_error(service_error.access, "Access denied", 189 proof=proof) 283 190 else: 284 191 # See if this is a replay of an earlier succeeded StartSegment - … … 338 245 'allocID': req['allocID'], 339 246 'allocationLog': "Allocatation complete", 340 'segmentdescription': { 'topdldescription': topo.to_dict() } 247 'segmentdescription': { 'topdldescription': topo.to_dict() }, 248 'proof': proof.to_dict(), 341 249 } 342 250 retval = copy.deepcopy(self.state[aid]['started']) … … 362 270 self.log.debug("Terminate request for %s" %aid) 363 271 # Check authorization 364 if not self.auth.check_attribute(fid, auth_attr): 365 raise service_error(service_error.access, "Access denied") 272 access_ok, proof = self.auth.check_attribute(fid, auth_attr, 273 with_proof=True) 274 if not access_ok: 275 raise service_error(service_error.access, "Access denied", 276 proof=proof) 366 277 367 278 # Authorized: remove the integer from the allocation. A more complex … … 377 288 self.state_lock.release() 378 289 379 return { 'allocID': req['allocID'] }290 return { 'allocID': req['allocID'], 'proof': proof.to_dict() } -
fedd/federation/thread_pool.py
rac15159 r0a49bd7 4 4 import time 5 5 from threading import Lock, Thread, Condition 6 from service_error import service_error 6 7 7 8 class thread_pool: -
fedd/federation/util.py
rac15159 r0a49bd7 8 8 9 9 import httplib 10 11 from optparse import OptionParser 10 12 11 13 from socket import sslerror … … 95 97 self.set_allow_unknown_ca(True) 96 98 self.set_verify(SSL.verify_peer, 10, callback=callb) 99 100 class file_expanding_opts(OptionParser): 101 def expand_file(self, option, opt_str, v, p): 102 """ 103 Store the given value to the given destination after expanding home 104 directories. 105 """ 106 setattr(p.values, option.dest, os.path.expanduser(v)) 107 108 def __init__(self, usage=None, version=None): 109 OptionParser.__init__(self) 110 97 111 98 112 def read_simple_accessdb(fn, auth, mask=[]): … … 360 374 # This should be a one-iteration loop 361 375 for c in context.credentials(): 362 ids.add( c.issuer_cert())363 attrs.add( c.attribute_cert())376 ids.add(str(c.issuer_cert())) 377 attrs.add(str(c.attribute_cert())) 364 378 365 379 return list(ids), list(attrs) -
fedd/init_abac_authorizer.py
rac15159 r0a49bd7 4 4 import os, os.path 5 5 6 from optparse import OptionParser6 from federation.util import file_expanding_opts 7 7 from federation.authorizer import abac_authorizer 8 8 9 class Parser( OptionParser):9 class Parser(file_expanding_opts): 10 10 def __init__(self): 11 OptionParser.__init__(self, usage='%prog [options]') 12 self.add_option('--cert', dest='cert', help='Identity certificate') 13 self.add_option('--key', dest='key', help='Identity key') 11 file_expanding_opts.__init__(self, usage='%prog [options]') 12 self.add_option('--cert', dest='cert', 13 action='callback', callback=self.expand_file, type='str', 14 help='Identity certificate') 15 self.add_option('--key', dest='key', 16 action='callback', callback=self.expand_file, type='str', 17 help='Identity key') 14 18 self.add_option('--policy', dest='policy', 19 action='callback', callback=self.expand_file, type='str', 15 20 help='ABAC policy certificates') 16 self.add_option('--dir', dest='out_dir', help='directory to save into') 21 self.add_option('--dir', dest='out_dir', 22 action='callback', callback=self.expand_file, type='str', 23 help='directory to save into') 17 24 18 25 parser = Parser() -
fedd/setup.py
rac15159 r0a49bd7 4 4 5 5 setup(name='fedd', 6 version='3. 01',6 version='3.20a', 7 7 description='DETER Federation daemon', 8 8 author='Ted Faber', … … 13 13 requires=['ZSI(>=2.0)', 'M2Crypto'], 14 14 provides=['federation'], 15 scripts=['confirm_sshkey.py', 'exp_access_db.py', 'fedd.py', 16 'fedd_client.py', 'fedd_create.py', 'fedd_ftopo.py', 15 scripts=['access_to_abac.py', 'cert_to_fedid.py', 'confirm_sshkey.py', 16 'creddy_split.py', 'dump_abac_authorizer.py', 'exp_access_db.py', 17 'fedd.py', 'fedd_client.py', 'fedd_create.py', 'fedd_ftopo.py', 17 18 'fedd_image.py', 'fedd_info.py', 'fedd_multiinfo.py', 18 19 'fedd_multistatus.py', 'fedd_new.py', 'fedd_ns2topdl.py', 19 'fedd_spewlog.py', 'fedd_terminate.py', 20 'fedid.py', ' user_to_project.py' ],20 'fedd_spewlog.py', 'fedd_terminate.py', 'fedd_to_abac.py', 21 'fedid.py', 'fedd_to_abac.py', 'user_to_project.py' ], 21 22 )
Note: See TracChangeset
for help on using the changeset viewer.