def __init__(self, create=False, subject=None, string=None, filename=None):
Certificate.__init__(self, create, subject, string, filename)
+ def create_similar(self):
+ return Credential()
+
def set_gid_caller(self, gid):
self.gidCaller = gid
"privileges": None,
"delegate": self.delegate}
if self.gidCaller:
- dict["gidCaller"] = self.gidCaller.save_to_string()
+ dict["gidCaller"] = self.gidCaller.save_to_string(save_parents=True)
if self.gidObject:
- dict["gidObject"] = self.gidObject.save_to_string()
+ dict["gidObject"] = self.gidObject.save_to_string(save_parents=True)
if self.privileges:
dict["privileges"] = self.privileges.save_to_string()
str = xmlrpclib.dumps((dict,), allow_none=True)
# do the normal certificate verification stuff
Certificate.verify_chain(self, trusted_certs)
- if parent:
+ if self.parent:
# make sure the parent delegated rights to the child
- if not parent.delegate:
- raise MissingDelegateBit(self.get_subject())
+ if not self.parent.get_delegate():
+ raise MissingDelegateBit(self.parent.get_subject())
# XXX todo: make sure child rights are a subset of parent rights
return
- def dump(self):
+ def dump(self, dump_parents=False):
print "CREDENTIAL", self.get_subject()
print " privs:", self.get_privileges().save_to_string()
print " gidCaller:"
gidCaller = self.get_gid_caller()
if gidCaller:
- gidCaller.dump(indent=8)
+ gidCaller.dump(8, dump_parents)
print " gidObject:"
gidObject = self.get_gid_object()
if gidObject:
- gidObject.dump(indent=8)
+ gidObject.dump(8, dump_parents)
print " delegate:", self.get_delegate()
+ if self.parent and dump_parents:
+ print "PARENT",
+ self.parent.dump(dump_parents)
+
from gid import *
from credential import *
from record import *
+from geniticket import *
+
+# ServerException, ExceptionUnmarshaller
+#
+# Used to convert server exception strings back to an exception.
+# from usenet, Raghuram Devarakonda
+
+class ServerException(Exception):
+ pass
+
+class ExceptionUnmarshaller(xmlrpclib.Unmarshaller):
+ def close(self):\r
+ try:\r
+ return xmlrpclib.Unmarshaller.close(self)\r
+ except xmlrpclib.Fault, e:\r
+ raise ServerException(e.faultString)
# GeniTransport
#
else:\r
return httplib.HTTPS(host, None, key_file=self.key_file, cert_file=self.cert_file) #**(x509 or {}))\r
\r
+ def getparser(self): \r
+ unmarshaller = ExceptionUnmarshaller() \r
+ parser = xmlrpclib.ExpatParser(unmarshaller) \r
+ return parser, unmarshaller\r
+\r
# GeniClient:\r
#\r
# Class for performing GeniClient operations.\r
self.transport = GeniTransport()
self.transport.key_file = self.key_file
self.transport.cert_file = self.cert_file
- self.server = xmlrpclib.ServerProxy(self.url, self.transport)
+ self.server = xmlrpclib.ServerProxy(self.url, self.transport, allow_none=True)
+
+ # -------------------------------------------------------------------------
+ # Registry Interface
+ # -------------------------------------------------------------------------
+
+ def create_gid(self, cred, name, uuid, pkey_string):
+ gid_str = self.server.create_gid(cred.save_to_string(save_parents=True), name, uuid, pkey_string)
+ return GID(string=gid_str)
def get_gid(self, name):
gid_str_list = self.server.get_gid(name)
# get_credential(..., cred=None,...)
def get_self_credential(self, type, name):
- cred_str = self.server.get_self_credential(type, name)
- return Credential(string = cred_str)
+ cred_str = self.server.get_self_credential(type, name)
+ return Credential(string = cred_str)
def get_credential(self, cred, type, name):
- cred_str = self.server.get_credential(cred.save_to_string(), type, name)
- return Credential(string = cred_str)
+ if cred == None:
+ return self.get_self_credential(type, name)
+ cred_str = self.server.get_credential(cred.save_to_string(save_parents=True), type, name)
+ return Credential(string = cred_str)
+
+ def list(self, cred):
+ result_dict_list = self.server.list(cred.save_to_string(save_parents=True))
+ result_rec_list = []
+ for dict in result_dict_list:
+ result_rec_list.append(GeniRecord(dict=dict))
+ return result_rec_list
+
+ def register(self, cred, record):
+ gid_str = self.server.register(cred.save_to_string(save_parents=True), record.as_dict())
+ return GID(string = gid_str)
+
+ def remove(self, cred, record):
+ result = self.server.remove(cred.save_to_string(save_parents=True), record.as_dict())
+ return result
def resolve(self, cred, name):
- result_dict_list = self.server.resolve(cred.save_to_string(), name)
- result_rec_list = []
- for dict in result_dict_list:
- result_rec_list.append(GeniRecord(dict=dict))
- return result_rec_list
+ result_dict_list = self.server.resolve(cred.save_to_string(save_parents=True), name)
+ result_rec_list = []
+ for dict in result_dict_list:
+ result_rec_list.append(GeniRecord(dict=dict))
+ return result_rec_list
+
+ def update(self, cred, record):
+ result = self.server.update(cred.save_to_string(save_parents=True), record.as_dict())
+ return result
+
+ # ------------------------------------------------------------------------
+ # Slice Interface
+ # ------------------------------------------------------------------------
+
+ def start_slice(self, cred):
+ result = self.server.start_slice(cred.save_to_string(save_parents=True))
+ return result
+
+ def stop_slice(self, cred):
+ result = self.server.stop_slice(cred.save_to_string(save_parents=True))
+ return result
+
+ def reset_slice(self, cred):
+ result = self.server.reset_slice(cred.save_to_string(save_parents=True))
+ return result
+
+ def delete_slice(self, cred):
+ result = self.server.delete_slice(cred.save_to_string(save_parents=True))
+ return result
+
+ def list_slices(self, cred):
+ result = self.server.list_slices(cred.save_to_string(save_parents=True))
+ return result
+
+ def get_ticket(self, cred, name, rspec):
+ ticket_str = self.server.get_ticket(cred.save_to_string(save_parents=True), name, rspec)
+ ticket = Ticket(string=ticket_str)
+ return ticket
+
+ def redeem_ticket(self, ticket):
+ result = self.server.redeem_ticket(ticket.save_to_string(save_parents=True))
+ return result
+
import SimpleXMLRPCServer
+import sys
+import traceback
import SocketServer
import BaseHTTPServer\r
import SimpleHTTPServer\r
"""\r
self.logRequests = logRequests\r
\r
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, None, None)\r
+ SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, True, None)\r
SocketServer.BaseServer.__init__(self, server_address, HandlerClass)\r
ctx = SSL.Context(SSL.SSLv23_METHOD)\r
ctx.use_privatekey_file(key_file)\r
self.server_bind()\r
self.server_activate()\r
\r
+ # _dispatch\r
+ #
+ # Convert an exception on the server to a full stack trace and send it to
+ # the client.
+
+ def _dispatch(self, method, params):\r
+ try:\r
+ return SimpleXMLRPCServer.SimpleXMLRPCDispatcher._dispatch(self, method, params)\r
+ except:\r
+ # can't use format_exc() as it is not available in jython yet (even\r
+ # in trunk).\r
+ type, value, tb = sys.exc_info()\r
+ raise xmlrpclib.Fault(1,''.join(traceback.format_exception(type, value, tb)))\r
+\r
# SecureXMLRpcRequestHandler\r
#\r
# taken from the web (XXX find reference). Implents HTTPS xmlrpc request handler\r
except: # This should only happen if the module is buggy\r
# internal error, report as HTTP server error\r
self.send_response(500)\r
+\r
self.end_headers()\r
else:\r
# got a valid XML RPC response\r
self.key = Keypair(filename = key_file)
self.cert = Certificate(filename = cert_file)
self.server = SecureXMLRPCServer((ip, port), SecureXMLRpcRequestHandler, key_file, cert_file)
+ self.trusted_cert_list = None
self.register_functions()
- def decode_authentication(self, cred_string):
+ def decode_authentication(self, cred_string, operation):
self.client_cred = Credential(string = cred_string)
self.client_gid = self.client_cred.get_gid_caller()
self.object_gid = self.client_cred.get_gid_object()
if not peer_cert.is_pubkey(self.client_gid.get_pubkey()):
raise ConnectionKeyGIDMismatch(self.client_gid.get_subject())
+ # make sure the client is allowed to perform the operation
+ if not self.client_cred.can_perform(operation):
+ raise InsufficientRights(operation)
+
+ if self.trusted_cert_list:
+ self.client_cred.verify_chain(self.trusted_cert_list)
+ if self.client_gid:
+ self.client_gid.verify_chain(self.trusted_cert_list)
+ if self.object_gid:
+ self.object_gid.verify_chain(self.trusted_cert_list)
+
# register_functions override this to add more functions
def register_functions(self):
self.server.register_function(self.noop)
--- /dev/null
+# tickets.py
+#
+# implements GENI tickets
+#
+
+from cert import *
+from rights import *
+from gid import *
+import xmlrpclib
+
+# Ticket is tuple:
+# (gidCaller, gidObject, attributes, rspec, delegate)
+#
+# gidCaller = GID of the caller performing the operation
+# gidObject = GID of the slice
+# attributes = slice attributes (keys, vref, instantiation, etc)
+# rspec = resources
+
+class Ticket(Certificate):
+ gidCaller = None
+ gidObject = None
+ attributes = {}
+ rspec = {}
+ delegate = False
+
+ def __init__(self, create=False, subject=None, string=None, filename=None):
+ Certificate.__init__(self, create, subject, string, filename)
+
+ def set_gid_caller(self, gid):
+ self.gidCaller = gid
+
+ def get_gid_caller(self):
+ if not self.gidCaller:
+ self.decode()
+ return self.gidCaller
+
+ def set_gid_object(self, gid):
+ self.gidObject = gid
+
+ def get_gid_object(self):
+ if not self.gidObject:
+ self.decode()
+ return self.gidObject
+
+ def set_attributes(self, gid):
+ self.attributes = gid
+
+ def get_attributes(self):
+ if not self.attributes:
+ self.decode()
+ return self.attributes
+
+ def set_rspec(self, gid):
+ self.rspec = gid
+
+ def get_rspec(self):
+ if not self.rspec:
+ self.decode()
+ return self.rspec
+
+ def set_delegate(self, delegate):
+ self.delegate = delegate
+
+ def get_delegate(self):
+ if not self.delegate:
+ self.decode()
+ return self.delegate
+
+ def encode(self):
+ dict = {"gidCaller": None,
+ "gidObject": None,
+ "attributes": self.attributes,
+ "rspec": self.rspec,
+ "delegate": self.delegate}
+ if self.gidCaller:
+ dict["gidCaller"] = self.gidCaller.save_to_string(save_parents=True)
+ if self.gidObject:
+ dict["gidObject"] = self.gidObject.save_to_string(save_parents=True)
+ str = xmlrpclib.dumps((dict,), allow_none=True)
+ self.set_data(str)
+
+ def decode(self):
+ data = self.get_data()
+ if data:
+ dict = xmlrpclib.loads(self.get_data())[0][0]
+ else:
+ dict = {}
+
+ self.attributes = dict.get("attributes", {})
+ self.rspec = dict.get("rspec", {})
+ self.delegate = dict.get("delegate", False)
+
+ gidCallerStr = dict.get("gidCaller", None)
+ if gidCallerStr:
+ self.gidCaller = GID(string=gidCallerStr)
+ else:
+ self.gidCaller = None
+
+ gidObjectStr = dict.get("gidObject", None)
+ if gidObjectStr:
+ self.gidObject = GID(string=gidObjectStr)
+ else:
+ self.gidObject = None
+
+ def dump(self, dump_parents=False):
+ print "TICKET", self.get_subject()
+
+ print " gidCaller:"
+ gidCaller = self.get_gid_caller()
+ if gidCaller:
+ gidCaller.dump(8, dump_parents)
+
+ print " gidObject:"
+ gidObject = self.get_gid_object()
+ if gidObject:
+ gidObject.dump(8, dump_parents)
+
+ print " attributes:"
+ for attrname in self.get_attributes().keys():
+ print " ", attrname, self.get_attributes()[attrname]
+
+ print " rspec:"
+ for attrname in self.get_rspec().keys():
+ print " ", attrname, self.get_rspec()[attrname]
+
+ if self.parent and dump_parents:
+ print "PARENT",
+ self.parent.dump(dump_parents)
import os
import report
from cert import *
+from credential import *
from gid import *
from misc import *
from config import *
+from geniticket import *
class AuthInfo():
hrn = None
+ gid_object = None
gid_filename = None
privkey_filename = None
dbinfo_filename = None
def __init__(self, hrn, gid_filename, privkey_filename, dbinfo_filename):
self.hrn = hrn
- self.gid_filename = gid_filename
+ self.set_gid_filename(gid_filename)
self.privkey_filename = privkey_filename
self.dbinfo_filename = dbinfo_filename
+ def set_gid_filename(self, fn):
+ self.gid_filename = fn
+ self.gid_object = None
+
def get_gid_object(self):
- return GID(filename = self.gid_filename)
+ if not self.gid_object:
+ self.gid_object = GID(filename = self.gid_filename)
+ return self.gid_object
def get_pkey_object(self):
return Keypair(filename = self.privkey_filename)
dict = eval(f.read())\r
f.close()\r
return dict\r
+\r
+ def update_gid_object(self, gid):\r
+ gid.save_to_file(self.gid_filename)\r
+ self.gid_object = gid\r
class Hierarchy():
def __init__(self, basedir="."):
- self.basedir = basedir
+ self.basedir = os.path.join(basedir, "authorities")
def get_auth_filenames(self, hrn):
leaf = get_leaf(hrn)
pkey.save_to_file(privkey_filename)
gid = self.create_gid(hrn, create_uuid(), pkey)
- gid.save_to_file(gid_filename)
+ gid.save_to_file(gid_filename, save_parents=True)
# XXX TODO: think up a better way for the dbinfo to work
auth_info = AuthInfo(hrn, gid_filename, privkey_filename, dbinfo_filename)
+ # check the GID and see if it needs to be refreshed
+ gid = auth_info.get_gid_object()
+ gid_refreshed = self.refresh_gid(gid)
+ if gid != gid_refreshed:
+ auth_info.update_gid_object(gid_refreshed)
+
return auth_info
def create_gid(self, hrn, uuid, pkey):
- parent_hrn = get_authority(hrn)
-
gid = GID(subject=hrn, uuid=uuid, hrn=hrn)
+ parent_hrn = get_authority(hrn)
if not parent_hrn:
# if there is no parent hrn, then it must be self-signed. this
# is where we terminate the recursion
return gid
+ def get_auth_cred(self, hrn):
+ auth_info = self.get_auth_info(hrn)
+ gid = auth_info.get_gid_object()
+
+ cred = Credential(subject=hrn)
+ cred.set_gid_caller(gid)
+ cred.set_gid_object(gid)
+ cred.set_privileges("authority")
+ cred.set_delegate(True)
+ cred.set_pubkey(auth_info.get_gid_object().get_pubkey())
+
+ parent_hrn = get_authority(hrn)
+ if not parent_hrn:
+ # if there is no parent hrn, then it must be self-signed. this
+ # is where we terminate the recursion
+ cred.set_issuer(auth_info.get_pkey_object(), hrn)
+ else:
+ # we need the parent's private key in order to sign this GID
+ parent_auth_info = self.get_auth_info(parent_hrn)
+ cred.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn)
+ cred.set_parent(self.get_auth_cred(parent_hrn))
+
+ cred.encode()
+ cred.sign()
+
+ return cred
+
+ # this looks almost the same as get_auth_cred, but works for tickets
+ # XXX does similarity imply there should be more code re-use?
+ def get_auth_ticket(self, hrn):
+ auth_info = self.get_auth_info(hrn)
+ gid = auth_info.get_gid_object()
+
+ ticket = Ticket(subject=hrn)
+ ticket.set_gid_caller(gid)
+ ticket.set_gid_object(gid)
+ ticket.set_delegate(True)
+ ticket.set_pubkey(auth_info.get_gid_object().get_pubkey())
+
+ parent_hrn = get_authority(hrn)
+ if not parent_hrn:
+ # if there is no parent hrn, then it must be self-signed. this
+ # is where we terminate the recursion
+ ticket.set_issuer(auth_info.get_pkey_object(), hrn)
+ else:
+ # we need the parent's private key in order to sign this GID
+ parent_auth_info = self.get_auth_info(parent_hrn)
+ ticket.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn)
+ ticket.set_parent(self.get_auth_cred(parent_hrn))
+
+ ticket.encode()
+ ticket.sign()
+
+ return ticket
+