check in latest updates to documentation
authorScott Baker <bakers@cs.arizona.edu>
Fri, 3 Oct 2008 00:33:50 +0000 (00:33 +0000)
committerScott Baker <bakers@cs.arizona.edu>
Fri, 3 Oct 2008 00:33:50 +0000 (00:33 +0000)
26 files changed:
util/cert.py
util/config.py
util/credential.py
util/db.py [deleted file]
util/excep.pyc
util/geniclient.py
util/geniserver.py
util/gid.py
util/hierarchy.py
util/misc.py
util/pl_to_geni.py [deleted file]
util/record.py
util/rights.py
util/sec/certgen.py [deleted file]
util/sec/certgen.pyc [deleted file]
util/sec/certgen2.py [deleted file]
util/sec/certgen_m2crypto.py [deleted file]
util/sec/certs/den.py [deleted file]
util/sec/certs/gen.py [deleted file]
util/sec/certs/jp.cert [deleted file]
util/sec/certs/jp.pkey [deleted file]
util/sec/certs/planetlab.cert [deleted file]
util/sec/certs/planetlab.pkey [deleted file]
util/sec/certs/usersoner.cert [deleted file]
util/sec/sec.py [deleted file]
util/sec/sec.pyc [deleted file]

index 1994af5..5d4796e 100644 (file)
@@ -192,13 +192,6 @@ class Certificate:
    def load_from_pyopenssl_x509(self, x509):
        self.cert = x509
 
-   ##
-   # Return another instance of the same class.
-   # XXX: probably will be deleted, can use cls() function instead
-
-   def create_similar(self):
-       return Certificate()
-
    ##
    # Load the certificate from a string
 
@@ -211,7 +204,7 @@ class Certificate:
        # if there are more certs, then create a parent and let the parent load
        # itself from the remainder of the string
        if len(parts) > 1:
-           self.parent = self.create_similar()
+           self.parent = self.__class__()
            self.parent.load_from_string(parts[1])
 
    ##
@@ -429,7 +422,9 @@ class Certificate:
         return self.parent
 
    ##
-   # Verify a chain of certificates.
+   # Verification examines a chain of certificates to ensure that each parent
+   # signs the child, and that some certificate in the chain is signed by a
+   # trusted certificate.
    #
    # Verification is a basic recursion: <pre>
    #     if this_certificate was signed by trusted_certs:\r
index 0854809..562aee1 100644 (file)
@@ -1,10 +1,18 @@
-# config.py
+##
+# Geniwrapper Configuration Info
 #
-# geniwrapper configuration info
+# This module holds configuration parameters for geniwrapper. There are two
+# main pieces of information that are used: the database connection and
+# the PLCAPI connection
+##
+
+##
+# Geniwrapper uses a MYSQL database to store records. This database may be
+# co-located with the PLC database, or it may be a separate database. The
+# following parameters define the connection to the database.
 #
-# this module holds configuration parameters for geniwrapper. The wrapper
-# needs an account to connect to PLC with and a database to store geni
-# tables
+# Note that Geniwrapper does not access any of the PLC databases directly via
+# a mysql connection; All PLC databases are accessed via PLCAPI.
 
 def get_default_dbinfo():
     dbinfo={}
@@ -16,4 +24,21 @@ def get_default_dbinfo():
 
     return dbinfo
 
+##
+# Geniwrapper uses a PLCAPI connection to perform operations on the registry,
+# such as creating and deleting slices. This connection requires an account
+# on the PLC server with full administrator access.
+#
+# The Url parameter controls whether the connection uses PLCAPI directly (i.e.
+# Geniwrapper is located on the same machine as PLC), or uses a XMLRPC connection
+# to the PLC machine. If you wish to use the API directly, then remove the Url
+# field from the dictionary. 
+
+def get_pl_auth():
+    pl_auth = {'Username': 'root@198.0.0.132',
+    'AuthMethod': 'password',\r
+    'AuthString':  'root',\r
+    "Url": "https://localhost:443/PLCAPI/"\r
+    }\r
 
+    return pl_auth
index 0daaf42..697adf0 100644 (file)
@@ -1,9 +1,9 @@
 ##
-#
 # Implements Geni Credentials
 #
 # Credentials are layered on top of certificates, and are essentially a
 # certificate that stores a tuple of parameters.
+##
 
 from cert import *
 from rights import *
@@ -189,6 +189,8 @@ class Credential(Certificate):
     # addition to the checks for ordinary certificates, verification also
     # ensures that the delegate bit was set by each parent in the chain. If
     # a delegate bit was not set, then an exception is thrown.
+    #
+    # Each credential must be a subset of the rights of the parent.
 
     def verify_chain(self, trusted_certs = None):
         # do the normal certificate verification stuff
diff --git a/util/db.py b/util/db.py
deleted file mode 100644 (file)
index 590a002..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-import os
-from pg import DB
-from excep import *
-from tree import *
-from util import *
-
-#planetlab authentication structure
-pl_auth = {'Username': 'ssevinc@princeton.edu',        # User account
-'AuthMethod': 'password',        # Type of auth this is. Can be password, session ...
-'AuthString':  'Ss3928Ee' # the password for this account
-} 
-
-def get_plDB_conn():
-    dbname = 'plDB'
-    address = 'localhost'
-    port = 5433
-    user = 'postgres'
-    password = '111'
-    cnx = DB(dbname, address, port=port, user=user, passwd=password)
-    return cnx
-    
-#copy the pl db info to requester
-def get_plDB_info(dst):
-    dst.db_name = 'plDB'
-    dst.address = 'localhost'
-    dst.port = 5433
-    dst.user = 'postgres'
-    dst.password = '111'
-
-
-#determines the database info of a given hrn
-#if the hrn does not exist in the tree hierarchy None is returned
-def determine_dbinfo(hrn, tree):
-    info = tree.tree_lookup(hrn)
-    if info == None:
-        return None
-    else:
-        db_info = info.node_data['db_info']
-        cnx = DB(db_info.db_name, db_info.address, port = db_info.port, user = db_info.user, passwd = db_info.password)
-        tablename = db_info.table_name
-        return [cnx, tablename]
-
-#convert the parameter list to query string suitable for supplying to database queries
-#input: query type, table name and field-value pairs
-def generate_querystr(type, table, dict):
-    querystr = ""
-    if type == 'INSERT':
-        keys = dict.keys()
-        str1 = keys[0]
-        for i in range(1, len(keys)):
-            str1 = str1 + ','+ keys[i]
-        str2 = ""
-        for i in range(len(keys)-1):
-            if isinstance(dict[keys[i]],str):
-                str2 = str2 + "'" + dict[keys[i]] + "', " 
-            else:
-                str2 = str2 + str(dict[keys[i]]) + ", "
-        if isinstance(dict[keys[len(keys)-1]],str):
-            str2 = str2 + "'" + dict[keys[len(keys)-1]] + "'" 
-        else:
-            str2 = str2 + str(dict[keys[len(keys)-1]]) 
-        querystr = "INSERT INTO "+table+ "(" + str1 + ") VALUES(" + str2 + ")"
-    elif type == 'UPDATE':
-        str1 = ""
-        keys = dict.keys()
-        for i in range(len(keys)-1):
-            if keys[i] != 'hrn':
-                if isinstance(dict[keys[i]],str):
-                    str1 = str1 + keys[i] + " = '" + dict[keys[i]] + "', " 
-                else:
-                    str1 = str1 + keys[i] + " = " + dict[keys[i]] + ", " 
-        if keys[len(keys)-1] != 'hrn':
-            if isinstance(dict[keys[len(keys)-1]],str):
-                str1 = str1 + keys[len(keys)-1] + " = '" + dict[keys[len(keys)-1]] + "'" 
-            else:
-                str1 = str1 + keys[len(keys)-1] + " = '" + dict[keys[len(keys)-1]]
-        querystr = "UPDATE "+table+ " SET " + str1 + " WHERE hrn = '"+get_leaf(dict["hrn"])+"'"
-    elif type == 'DELETE':
-        querystr = "DELETE FROM "+table+" WHERE hrn = '"+get_leaf(dict["hrn"])+"'"
-    return querystr
-            
index 3aa377e..edb7e87 100644 (file)
Binary files a/util/excep.pyc and b/util/excep.pyc differ
index 2de52e2..accf658 100644 (file)
@@ -1,10 +1,10 @@
-# geniclient.py
-#
-# geni client
-#
-# implements the client-side of the GENI API.
+##
+# This module implements the client-side of the Geni API. Stubs are provided
+# that convert the supplied parameters to the necessary format and send them
+# via XMLRPC to a Geni Server.
 #
 # TODO: Investigate ways to combine this with existing PLC API?
+##
 
 import xmlrpclib
 
@@ -13,6 +13,7 @@ from credential import *
 from record import *
 from geniticket import *
 
+##
 # ServerException, ExceptionUnmarshaller
 #
 # Used to convert server exception strings back to an exception.
@@ -28,6 +29,7 @@ class ExceptionUnmarshaller(xmlrpclib.Unmarshaller):
         except xmlrpclib.Fault, e:\r
             raise ServerException(e.faultString)
 
+##
 # GeniTransport
 #
 # A transport for XMLRPC that works on top of HTTPS
@@ -49,19 +51,30 @@ class GeniTransport(xmlrpclib.Transport):
         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
+    def getparser(self):\r
+        unmarshaller = ExceptionUnmarshaller()\r
+        parser = xmlrpclib.ExpatParser(unmarshaller)\r
         return parser, unmarshaller\r
 \r
-# GeniClient:\r
+##\r
+# The GeniClient class provides stubs for executing Geni operations. A given\r
+# client object connects to one server. To connect to multiple servers, create\r
+# multiple GeniClient objects.\r
 #\r
-# Class for performing GeniClient operations.\r
+# The Geni protocol uses an HTTPS connection, and the client's side of the\r
+# connection uses his private key. Generally, this private key must match the\r
+# public key that is containing in the GID that the client is providing for\r
+# those functions that take a GID.\r
 \r
 class GeniClient():
-    # url = url of server
-    # key_file = private key file of client
-    # cert_file = x.509 cert of client
+    ##
+    # Create a new GeniClient object.
+    #
+    # @param url is the url of the server
+    # @param key_file = private key file of client
+    # @param cert_file = x.509 cert containing the client's public key. This
+    #      could be a GID certificate, or any x.509 cert.
+
     def __init__(self, url, key_file, cert_file):
        self.url = url
        self.key_file = key_file
@@ -75,10 +88,31 @@ class GeniClient():
     # Registry Interface
     # -------------------------------------------------------------------------
 
+    ##
+    # Create a new GID. For MAs and SAs that are physically located on the
+    # registry, this allows a owner/operator/PI to create a new GID and have it
+    # signed by his respective authority.
+    #
+    # @param cred credential of caller
+    # @param name hrn for new GID
+    # @param uuid unique identifier for new GID
+    # @param pkey_string public-key string (TODO: why is this a string and not a keypair object?)
+    #
+    # @return a GID object
+
     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)
 
+    ##
+    # Retrieve the GID for an object. This function looks up a record in the
+    # registry and returns the GID of the record if it exists.
+    # TODO: Is this function needed? It's a shortcut for Resolve()
+    #
+    # @param name hrn to look up
+    #
+    # @return a GID object
+
     def get_gid(self, name):
        gid_str_list = self.server.get_gid(name)
        gid_list = []
@@ -86,22 +120,51 @@ class GeniClient():
            gid_list.append(GID(string=str))
        return gid_list
 
-    # get_self_credential
+    ##
+    # Get_self_credential a degenerate version of get_credential used by a
+    # client to get his initial credential when he doesn't have one. This is
+    # the same as get_credential(..., cred=None,...).
     #
-    # a degenerate version of get_credential used by a client to get his
-    # initial credential when he doesn't have one. The same as calling
-    # get_credential(..., cred=None,...)
+    # The registry ensures that the client is the principal that is named by
+    # (type, name) by comparing the public key in the record's GID to the
+    # private key used to encrypt the client-side of the HTTPS connection. Thus
+    # it is impossible for one principal to retrieve another principal's
+    # credential without having the appropriate private key.
+    #
+    # @param type type of object (user | slice | sa | ma | node
+    # @param name human readable name of object
+    #
+    # @return a credential object
 
     def get_self_credential(self, type, name):
         cred_str = self.server.get_self_credential(type, name)
         return Credential(string = cred_str)
 
+    ##
+    # Retrieve a credential for an object.
+    #
+    # If cred==None, then the behavior reverts to get_self_credential()
+    #
+    # @param cred credential object specifying rights of the caller
+    # @param type type of object (user | slice | sa | ma | node)
+    # @param name human readable name of object
+    #
+    # @return a credental object
+
     def get_credential(self, cred, type, name):
         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)
 
+    ##
+    # List the records in an authority. The objectGID in the supplied credential
+    # should name the authority that will be listed.
+    #
+    # @param cred credential object specifying rights of the caller
+    #
+    # @return list of record objects
+
     def list(self, cred):
         result_dict_list = self.server.list(cred.save_to_string(save_parents=True))
         result_rec_list = []
@@ -109,14 +172,49 @@ class GeniClient():
              result_rec_list.append(GeniRecord(dict=dict))
         return result_rec_list
 
+    ##
+    # Register an object with the registry. In addition to being stored in the
+    # Geni database, the appropriate records will also be created in the
+    # PLC databases.
+    #
+    # The geni_info and/or pl_info fields must in the record must be filled
+    # out correctly depending on the type of record that is being registered.
+    #
+    # TODO: The geni_info member of the record should be parsed and the pl_info
+    # adjusted as necessary (add/remove users from a slice, etc)
+    #
+    # @param cred credential object specifying rights of the caller
+    # @return record to register
+    #
+    # @return GID object for the newly-registered record
+
     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)
 
+    ##
+    # Remove an object from the registry. If the object represents a PLC object,
+    # then the PLC records will also be removed.
+    #
+    # @param cred credential object specifying rights of the caller
+    # @param record record to register. The only relevant
+    #     fields of the record are 'name' and 'type', which are used to lookup
+    #     the current copy of the record in the Geni database, to make sure
+    #     that the appopriate record is removed.
+
     def remove(self, cred, record):
         result = self.server.remove(cred.save_to_string(save_parents=True), record.as_dict())
         return result
 
+    ##
+    # Resolve an object in the registry. A given HRN may have multiple records
+    # associated with it, and therefore multiple records may be returned. The
+    # caller should check the type fields of the records to find the one that
+    # he is interested in.
+    #
+    # @param cred credential object specifying rights of the caller
+    # @param name human readable name of object
+
     def resolve(self, cred, name):
         result_dict_list = self.server.resolve(cred.save_to_string(save_parents=True), name)
         result_rec_list = []
@@ -124,6 +222,20 @@ class GeniClient():
              result_rec_list.append(GeniRecord(dict=dict))
         return result_rec_list
 
+    ##
+    # Update an object in the registry. Currently, this only updates the
+    # PLC information associated with the record. The Geni fields (name, type,
+    # GID) are fixed.
+    #
+    # The record is expected to have the pl_info field filled in with the data
+    # that should be updated.
+    #
+    # TODO: The geni_info member of the record should be parsed and the pl_info
+    # adjusted as necessary (add/remove users from a slice, etc)
+    #
+    # @param cred credential object specifying rights of the caller
+    # @param record a record object to be updated
+
     def update(self, cred, record):
         result = self.server.update(cred.save_to_string(save_parents=True), record.as_dict())
         return result
@@ -132,31 +244,90 @@ class GeniClient():
     # Slice Interface
     # ------------------------------------------------------------------------
 
+    ##
+    # Start a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
     def start_slice(self, cred):
         result = self.server.start_slice(cred.save_to_string(save_parents=True))
         return result
 
+    ##
+    # Stop a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
     def stop_slice(self, cred):
         result = self.server.stop_slice(cred.save_to_string(save_parents=True))
         return result
 
+    ##
+    # Reset a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
     def reset_slice(self, cred):
         result = self.server.reset_slice(cred.save_to_string(save_parents=True))
         return result
 
+    ##
+    # Delete a slice.
+    #
+    # @param cred a credential identifying the caller (callerGID) and the slice
+    #     (objectGID)
+
     def delete_slice(self, cred):
         result = self.server.delete_slice(cred.save_to_string(save_parents=True))
         return result
 
+    ##
+    # List the slices on a component.
+    #
+    # @param cred credential object that authorizes the caller
+    #
+    # @return a list of slice names
+
     def list_slices(self, cred):
         result = self.server.list_slices(cred.save_to_string(save_parents=True))
         return result
 
+    ##
+    # Retrieve a ticket. This operation is currently implemented on the
+    # registry (see SFA, engineering decisions), and is not implemented on
+    # components.
+    #
+    # The ticket is filled in with information from the PLC database. This
+    # information includes resources, and attributes such as user keys and
+    # initscripts.
+    #
+    # @param cred credential object
+    # @param name name of the slice to retrieve a ticket for
+    # @param rspec resource specification dictionary
+    #
+    # @return a ticket object
+
     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
 
+    ##
+    # Redeem a ticket. This operation is currently implemented on the
+    # component.
+    #
+    # The ticket is submitted to the node manager, and the slice is instantiated
+    # or updated as appropriate.
+    #
+    # TODO: This operation should return a sliver credential and indicate
+    # whether or not the component will accept only sliver credentials, or
+    # will accept both sliver and slice credentials.
+    #
+    # @param ticket a ticket object containing the ticket
+
     def redeem_ticket(self, ticket):
         result = self.server.redeem_ticket(ticket.save_to_string(save_parents=True))
         return result
index b58080d..b8cc047 100644 (file)
@@ -1,11 +1,10 @@
-# geniserver.py
-#
-# geniwrapper server
-#
-# implements a general-purpose server layer for geni. This should be usable on
-# the registry, component, or other interfaces.
+##
+# This module implements a general-purpose server layer for geni.
+# The same basic server should be usable on the registry, component, or
+# other interfaces.
 #
 # TODO: investigate ways to combine this with existing PLC server?
+##
 
 import SimpleXMLRPCServer
 
@@ -23,9 +22,8 @@ from credential import *
 import socket, os\r
 from OpenSSL import SSL\r
 \r
-# verify_callback\r
-#\r
-# verification callback for pyOpenSSL. We do our own checking of keys because\r
+##\r
+# Verification callback for pyOpenSSL. We do our own checking of keys because\r
 # we have our own authentication spec. Thus we disable several of the normal\r
 # prohibitions that OpenSSL places on certificates\r
 \r
@@ -74,9 +72,8 @@ def verify_callback(conn, x509, err, depth, preverify):
 
     return 0\r
 \r
-# SecureXMLServer\r
-#\r
-# taken from the web (XXX find reference). Implements an HTTPS xmlrpc server\r
+##\r
+# Taken from the web (XXX find reference). Implements an HTTPS xmlrpc server\r
 
 class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLRPCDispatcher):\r
     def __init__(self, server_address, HandlerClass, key_file, cert_file, logRequests=True):\r
@@ -112,8 +109,7 @@ class SecureXMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLR
             type, value, tb = sys.exc_info()\r
             raise xmlrpclib.Fault(1,''.join(traceback.format_exception(type, value, tb)))\r
 \r
-# SecureXMLRpcRequestHandler\r
-#\r
+##\r
 # taken from the web (XXX find reference). Implents HTTPS xmlrpc request handler\r
 \r
 class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):\r
@@ -160,10 +156,7 @@ class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
             self.wfile.flush()\r
             self.connection.shutdown() # Modified here!\r
 
-# GeniServer
-#
-# Class for a general purpose geni server.
-#
+##
 # Implements an HTTPS XML-RPC server. Generally it is expected that GENI
 # functions will take a credential string, which is passed to
 # decode_authentication. Decode_authentication() will verify the validity of
@@ -171,6 +164,15 @@ class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
 # GID supplied in the credential.
 
 class GeniServer():
+
+    ##
+    # Create a new GeniServer object.
+    #
+    # @param ip the ip address to listen on
+    # @param port the port to listen on
+    # @param key_file private key filename of registry
+    # @param cert_file certificate filename containing public key (could be a GID file)
+
     def __init__(self, ip, port, key_file, cert_file):
         self.key = Keypair(filename = key_file)
         self.cert = Certificate(filename = cert_file)
@@ -178,6 +180,12 @@ class GeniServer():
         self.trusted_cert_list = None
         self.register_functions()
 
+    ##
+    # Decode the credential string that was submitted by the caller. Several
+    # checks are performed to ensure that the credential is valid, and that the
+    # callerGID included in the credential matches the caller that is
+    # connected to the HTTPS connection.
+
     def decode_authentication(self, cred_string, operation):
         self.client_cred = Credential(string = cred_string)
         self.client_gid = self.client_cred.get_gid_caller()
@@ -203,15 +211,25 @@ class GeniServer():
             if self.object_gid:
                 self.object_gid.verify_chain(self.trusted_cert_list)
 
-    # register_functions override this to add more functions
+    ##
+    # Register functions that will be served by the XMLRPC server. This
+    # function should be overrided by each descendant class.
+
     def register_functions(self):
         self.server.register_function(self.noop)
 
+    ##
+    # Sample no-op server function. The no-op function decodes the credential
+    # that was passed to it.
+
     def noop(self, cred, anything):
         self.decode_authentication(cred)
 
         return anything
 
+    ##
+    # Execute the server, serving requests forever. 
+
     def run(self):
         self.server.serve_forever()
 
index 7701e87..65aff6b 100644 (file)
@@ -1,21 +1,51 @@
-# gid.py
-#
-# implements GENI GID
+##
+# Implements GENI GID. GIDs are based on certificates, and the GID class is a
+# descendant of the certificate class.
+##
 
 from cert import *
 import uuid
 import xmlrpclib
 
-# GID is a tuplie:
-#    (uuid, hrn, public_key)
+##
+# Create a new uuid. Returns the UUID as a string.
 
 def create_uuid():
     return str(uuid.uuid4().int)
 
+##
+# GID is a tuplie:
+#    (uuid, hrn, public_key)
+#
+# UUID is a unique identifier and is created by the python uuid module
+#    (or the utility function create_uuid() in gid.py).
+#
+# HRN is a human readable name. It is a dotted form similar to a backward domain\r
+#    name. For example, planetlab.us.arizona.bakers.\r
+#\r
+# PUBLIC_KEY is the public key of the principal identified by the UUID/HRN.\r
+# It is a Keypair object as defined in the cert.py module.\r
+#\r
+# It is expected that there is a one-to-one pairing between UUIDs and HRN,
+# but it is uncertain how this would be inforced or if it needs to be enforced.
+#
+# These fields are encoded using xmlrpc into the subjectAltName field of the
+# x509 certificate. Note: Call encode() once the fields have been filled in
+# to perform this encoding.
+
+
 class GID(Certificate):
     uuid = None
     hrn = None
 
+    ##
+    # Create a new GID object
+    #
+    # @param create If true, create the X509 certificate
+    # @param subject If subject!=None, create the X509 cert and set the subject name
+    # @param string If string!=None, load the GID from a string
+    # @param filename If filename!=None, load the GID from a file
+
     def __init__(self, create=False, subject=None, string=None, filename=None, uuid=None, hrn=None):
         Certificate.__init__(self, create, subject, string, filename)
         if uuid:
@@ -39,12 +69,22 @@ class GID(Certificate):
             self.decode()
         return self.hrn
 
+    ##
+    # Encode the GID fields and package them into the subject-alt-name field
+    # of the X509 certificate. This must be called prior to signing the
+    # certificate. It may only be called once per certificate.
+
     def encode(self):
         dict = {"uuid": self.uuid,
                 "hrn": self.hrn}
         str = xmlrpclib.dumps((dict,))
         self.set_data(str)
 
+    ##
+    # Decode the subject-alt-name field of the X509 certificate into the
+    # fields of the GID. This is automatically called by the various get_*()
+    # functions in this class.
+
     def decode(self):
         data = self.get_data()
         if data:
@@ -55,11 +95,41 @@ class GID(Certificate):
         self.uuid = dict.get("uuid", None)
         self.hrn = dict.get("hrn", None)
 
-    def dump(self, indent=0):
-        # TODO: implement indent
+    ##
+    # Dump the credential to stdout.
+    #
+    # @param indent specifies a number of spaces to indent the output
+    # @param dump_parents If true, also dump the parents of the GID
+
+    def dump(self, indent=0, dump_parents=False):
         print " "*indent, " hrn:", self.get_hrn()
         print " "*indent, "uuid:", self.get_uuid()
 
+        if self.parent and dump_parents:
+            print " "*indent, "parent:"
+            self.parent.dump(indent+4)
+
+    ##
+    # Verify the chain of authenticity of the GID. First perform the checks
+    # of the certificate class (verifying that each parent signs the child,
+    # etc). In addition, GIDs also confirm that the parent's HRN is a prefix
+    # of the child's HRN.
+    #
+    # Verifying these prefixes prevents a rogue authority from signing a GID
+    # for a principal that is not a member of that authority. For example,
+    # planetlab.us.arizona cannot sign a GID for planetlab.us.princeton.foo.
+
+    def verify_chain(self, trusted_certs = None):
+        # do the normal certificate verification stuff
+        Certificate.verify_chain(self, trusted_certs)
+
+        if self.parent:
+            # make sure the parent's hrn is a prefix of the child's hrn
+            if not self.get_hrn().startswith(self.parent.get_hrn()):
+                raise GidParentHrn(self.parent.get_subject())
+
+        return
+
 
 
 
index e83b4d4..a96ec56 100644 (file)
@@ -1,13 +1,16 @@
-# hierarchy.py
+##
+# This module implements a hierarchy of authorities and performs a similar
+# function as the "tree" module of the original geniwrapper prototype. An HRN
+# is assumed to be a string of authorities separated by dots. For example,
+# "planetlab.us.arizona.bakers". Each component of the HRN is a different
+# authority, with the last component being a leaf in the tree.
 #
-# hierarchy of GENI authorities
-#
-# This correspond's almost identically to the functionality of Soner's
-# "tree" module. Each component of an HRN is stored in a different subdirectory.
-# Inside this subdirectory are:
+# Each authority is stored in a subdirectory on the registry. Inside this
+# subdirectory are several files:
 #      *.GID - GID file
 #      *.PKEY - private key file
 #      *.DBINFO - database info
+##
 
 import os
 import report
@@ -18,6 +21,10 @@ from misc import *
 from config import *
 from geniticket import *
 
+##
+# The AuthInfo class contains the information for an authority. This information
+# includes the GID, private key, and database connection information.
+
 class AuthInfo():
     hrn = None
     gid_object = None
@@ -25,38 +32,86 @@ class AuthInfo():
     privkey_filename = None
     dbinfo_filename = None
 
+    ##
+    # Initialize and authority object.
+    #
+    # @param hrn the human readable name of the authority
+    # @param gid_filename the filename containing the GID
+    # @param privkey_filename the filename containing the private key
+    # @param dbinfo_filename the filename containing the database info
+
     def __init__(self, hrn, gid_filename, privkey_filename, dbinfo_filename):
         self.hrn = hrn
         self.set_gid_filename(gid_filename)
         self.privkey_filename = privkey_filename
         self.dbinfo_filename = dbinfo_filename
 
+    ##
+    # Set the filename of the GID
+    #
+    # @param fn filename of file containing GID
+
     def set_gid_filename(self, fn):
         self.gid_filename = fn
         self.gid_object = None
 
+    ##
+    # Get the GID in the form of a GID object
+
     def get_gid_object(self):
         if not self.gid_object:
             self.gid_object = GID(filename = self.gid_filename)
         return self.gid_object
 
+    ##
+    # Get the private key in the form of a Keypair object
+
     def get_pkey_object(self):
         return Keypair(filename = self.privkey_filename)
 
+    ##
+    # Get the dbinfo in the form of a dictionary
+
     def get_dbinfo(self):
         f = file(self.dbinfo_filename)
         dict = eval(f.read())\r
         f.close()\r
         return dict\r
 \r
+    ##\r
+    # Replace the GID with a new one. The file specified by gid_filename is\r
+    # overwritten with the new GID object\r
+    #\r
+    # @param gid object containing new GID\r
+\r
     def update_gid_object(self, gid):\r
         gid.save_to_file(self.gid_filename)\r
         self.gid_object = gid\r
+\r
+##\r
+# The Hierarchy class is responsible for managing the tree of authorities.\r
+# Each authority is a node in the tree and exists as an AuthInfo object.\r
+#\r
+# The tree is stored on disk in a hierarchical manner than reflects the\r
+# structure of the tree. Each authority is a subdirectory, and each subdirectory\r
+# contains the GID, pkey, and dbinfo files for that authority (as well as\r
+# subdirectories for each sub-authority)\r
 
 class Hierarchy():
+    ##
+    # Create the hierarchy object.
+    #
+    # @param basedir the base directory to store the hierarchy in
+
     def __init__(self, basedir="."):
         self.basedir = os.path.join(basedir, "authorities")
 
+    ##
+    # Given a hrn, return the filenames of the GID, private key, and dbinfo
+    # files.
+    #
+    # @param hrn the human readable name of the authority
+
     def get_auth_filenames(self, hrn):
         leaf = get_leaf(hrn)
         parent_hrn = get_authority(hrn)
@@ -68,6 +123,12 @@ class Hierarchy():
 
         return (directory, gid_filename, privkey_filename, dbinfo_filename)
 
+    ##
+    # Check to see if an authority exists. An authority exists if it's disk
+    # files exist.
+    #
+    # @param the human readable name of the authority to check
+
     def auth_exists(self, hrn):
         (directory, gid_filename, privkey_filename, dbinfo_filename) = \
             self.get_auth_filenames(hrn)
@@ -76,6 +137,13 @@ class Hierarchy():
                os.path.exists(privkey_filename) and \
                os.path.exists(dbinfo_filename)
 
+    ##
+    # Create an authority. A private key for the authority and the associated
+    # GID are created and signed by the parent authority.
+    #
+    # @param hrn the human readable name of the authority to create
+    # @param create_parents if true, also create the parents if they do not exist
+
     def create_auth(self, hrn, create_parents=False):
         report.trace("Hierarchy: creating authority: " + hrn)
 
@@ -108,6 +176,13 @@ class Hierarchy():
         dbinfo_file.write(str(dbinfo))\r
         dbinfo_file.close()
 
+    ##
+    # Return the AuthInfo object for the specified authority. If the authority
+    # does not exist, then an exception is thrown. As a side effect, disk files
+    # and a subdirectory may be created to store the authority.
+    #
+    # @param hrn the human readable name of the authority to create.
+
     def get_auth_info(self, hrn):
         #report.trace("Hierarchy: getting authority: " + hrn)
 
@@ -127,6 +202,15 @@ class Hierarchy():
 
         return auth_info
 
+    ##
+    # Create a new GID. The GID will be signed by the authority that is it's
+    # immediate parent in the hierarchy (and recursively, the parents' GID
+    # will be signed by its parent)
+    #
+    # @param hrn the human readable name to store in the GID
+    # @param uuid the unique identifier to store in the GID
+    # @param pkey the public key to store in the GID
+
     def create_gid(self, hrn, uuid, pkey):
         gid = GID(subject=hrn, uuid=uuid, hrn=hrn)
 
@@ -147,6 +231,16 @@ class Hierarchy():
 
         return gid
 
+    ##
+    # Refresh a GID. The primary use of this function is to refresh the
+    # the expiration time of the GID. It may also be used to change the HRN,
+    # UUID, or Public key of the GID.
+    #
+    # @param gid the GID to refresh
+    # @param hrn if !=None, change the hrn
+    # @param uuid if !=None, change the uuid
+    # @param pubkey if !=None, change the public key
+
     def refresh_gid(self, gid, hrn=None, uuid=None, pubkey=None):
         # TODO: compute expiration time of GID, refresh it if necessary
         gid_is_expired = False
@@ -164,6 +258,13 @@ class Hierarchy():
 
         return gid
 
+    ##
+    # Retrieve an authority credential for an authority. The authority
+    # credential will contain the authority privilege and will be signed by
+    # the authority's parent.
+    #
+    # @param hrn the human readable name of the authority
+
     def get_auth_cred(self, hrn):
         auth_info = self.get_auth_info(hrn)
         gid = auth_info.get_gid_object()
@@ -190,9 +291,17 @@ class Hierarchy():
         cred.sign()
 
         return cred
-
-    # this looks almost the same as get_auth_cred, but works for tickets
+    ##
+    # Retrieve an authority ticket. An authority ticket is not actually a
+    # redeemable ticket, but only serves the purpose of being included as the
+    # parent of another ticket, in order to provide a chain of authentication
+    # for a ticket.
+    #
+    # This looks almost the same as get_auth_cred, but works for tickets
     # XXX does similarity imply there should be more code re-use?
+    #
+    # @param hrn the human readable name of the authority
+
     def get_auth_ticket(self, hrn):
         auth_info = self.get_auth_info(hrn)
         gid = auth_info.get_gid_object()
index 140c7b5..90c257b 100644 (file)
@@ -6,7 +6,7 @@ def get_leaf(hrn):
 
 def get_authority(hrn):
     parts = hrn.split(".")\r
-    return ".".join(parts[:-1])
+    return ".".join(parts[:-1])\r
 
 def get_auth_type(type):
     if (type=="slice") or (type=="user") or (type=="sa"):
@@ -20,7 +20,12 @@ def hrn_to_pl_slicename(hrn):
     parts = hrn.split(".")
     return parts[-2] + "_" + parts[-1]
 
+# assuming hrn is the hrn of an authority, return the plc authority name
 def hrn_to_pl_authname(hrn):
     parts = hrn.split(".")
     return parts[-1]
 
+# assuming hrn is the hrn of an authority, return the plc login_base
+def hrn_to_pl_login_base(hrn):
+    return hrn_to_pl_authname(hrn)
+
diff --git a/util/pl_to_geni.py b/util/pl_to_geni.py
deleted file mode 100644 (file)
index db07211..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-import sys
-from pg import DB
-from db import *
-from util import *
-
-PL_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
-        
-#given a login_base or site_id (which are ids of a site in Planetlab), determines the hierarchical name of it in GENI
-def site_to_auth(id_or_loginbase):
-    cnx = get_plDB_conn()
-    site_id = None
-    hrn = None
-    loginbase = None
-    if isinstance(id_or_loginbase, int):
-        site_id = id_or_loginbase
-        querystr = "SELECT login_base FROM sites WHERE site_id = "+str(id_or_loginbase)
-        res = cnx.query(querystr).dictresult()
-        if res:
-            loginbase = res[0]['login_base']
-        else:
-            return None
-    else:
-        loginbase = id_or_loginbase
-        #get site_id
-        querystr = "SELECT site_id FROM sites WHERE login_base = '"+loginbase+"'"
-        res = cnx.query(querystr).dictresult()
-        if res:
-            site_id = res[0]['site_id']
-        else:
-            return None
-    #search login_base in trees
-    (sr_tree, cr_tree) = get_tree_globals()
-    hrn = site_to_auth_rec(loginbase, sr_tree.my_tree)
-    if not hrn:
-        hrn = site_to_auth_rec(loginbase, cr_tree.my_tree)
-    if not hrn:
-        return None
-    else:
-        return (site_id, hrn)
-    
-def site_to_auth_rec(loginbase, treenode):
-    if treenode.info.login_base and treenode.info.login_base == loginbase:
-        return treenode.info.name
-    else:
-        for child in treenode.children:
-            name = site_to_auth_rec(loginbase, child)
-            if name:
-                return name
-    return None
-    
-def hrn_to_loginbase(hrn, algorithm=0):
-    hrn_arr = hrn.split('.')
-    j = len(hrn_arr)-2
-    alg_count = algorithm-1 
-    login_base = hrn_arr[len(hrn_arr)-1]
-    while j>=0 and alg_count>=0:
-        if alg_count == 0:
-            login_base = login_base+hrn_arr[j]
-        j = j-1
-        alg_count = alg_count-1
-    if len(login_base) > 20:
-        return login_base[0:20]
-    else:
-        return login_base
-        
-    
-#given an email or person_id (which are ids of a person in Planetlab), determined the last portion of hierarchical name of it in GENI
-def person_to_user(email, algorithm = 0):
-    hrn_suffix = ''
-    if algorithm == 0:
-        hrn_suffix = email.split('@')[0].replace('.','-')
-    elif algorithm == 1:
-        hrn_suffix = email.split('@')[0].replace('.','-')+'-'+email.split('@')[1].split('.')[0]
-    elif algorithm == 2:
-        hrn_suffix = email.replace('@','-')
-        hrn_suffix = hrn_suffix.replace('.','-')
-    return hrn_suffix
-    
-def plslice_to_slice(slice_name):
-    i = 0
-    while slice_name[i]!='_':
-        i = i+1
-    return slice_name[i+1:len(slice_name)]
-    
-def plnode_to_node(hostname, algorithm = 0):
-    hrn_suffix = ''
-    if algorithm == 0:
-        hrn_suffix = hostname.split('.')[0]
-    elif algorithm == 1:
-        hrn_suffix = hostname.split('.')[0]+'-'+hostname.split('.')[1]
-    elif algorithm == 2:
-        hrn_suffix = hrn_suffix.replace('.','-')
-    return hrn_suffix
-    
-def check_exists_pl(cnx, pointer, type):
-    exists = True
-    if type == 'SA' or type == 'MA':
-        res = cnx.query("SELECT deleted FROM sites WHERE site_id = "+str(pointer)).dictresult()
-        if len(res)==0 or res[0]['deleted'] == 't':
-            exists = False
-    elif type == 'slice':
-        res = cnx.query("SELECT is_deleted FROM slices WHERE slice_id = "+str(pointer)).dictresult()
-        if len(res)==0 or res[0]['is_deleted'] == 't':
-            exists = False
-    elif type == 'user':
-        res = cnx.query("SELECT deleted FROM persons WHERE person_id = "+str(pointer)).dictresult()
-        if len(res)==0 or res[0]['deleted'] == 't':
-            exists = False
-    elif type == 'node':
-        res = cnx.query("SELECT deleted FROM nodes WHERE node_id = "+str(pointer)).dictresult()
-        if len(res)==0 or res[0]['deleted'] == 't':
-            exists = False
-    return exists
-    
-def check_exists_geni(record, dbinfo):
-    cnx = dbinfo[0]
-    table = dbinfo[1] 
-    try:
-        #lookup in GENI tables
-        geni_res = cnx.query("SELECT * FROM "+table+" WHERE hrn = '"+get_leaf(record['g_params']["hrn"])+"' ").dictresult()
-        if geni_res:
-            return geni_res[0]
-        else:
-            return None
-    except:
-        return None
-        
-#fill the geni table with the records in PL database
-#login_base: indicates the site in PL
-#tablename: the GENI table name
-#type: 'slice' or 'component' indicating the registry type of the GENI table
-def populate_pl_data(login_base, tablename, type):
-    cnx = get_plDB_conn()
-    site_id = cnx.query("SELECT site_id FROM sites WHERE login_base='"+login_base+"';").dictresult()[0]['site_id']
-    
-    if type == 'slice': #slice registry
-        #populate user records
-        querystr = "SELECT p.person_id, p.email FROM persons as p, person_site as ps WHERE p.person_id = ps.person_id AND  ps.site_id = "+str(site_id)
-        users = cnx.query(querystr).dictresult()
-        for user in users:
-            new_hrn = person_to_user(user['email'])
-            existing = cnx.query("SELECT * FROM "+tablename+" WHERE hrn = '"+new_hrn+"'; ").dictresult()
-            if len(existing) > 0:
-                new_hrn = person_to_user(user['email'], 1)
-                existing = cnx.query("SELECT * FROM "+tablename+" WHERE hrn = '"+new_hrn+"'; ").dictresult()
-                if len(existing) > 0:
-                    new_hrn = person_to_user(user['email'], 2)
-            cnx.query("INSERT INTO "+tablename+"(hrn,type,wrapperurl,pointer) VALUES('"+new_hrn+"','user','local',"+str(user['person_id'])+")")
-        #populate slice records
-        querystr = "SELECT slice_id, name FROM slices WHERE site_id = "+str(site_id)
-        slices = cnx.query(querystr).dictresult()
-        for slice in slices:
-            slcname = slice['name'].split('_')
-            if slcname[len(slcname)-1] != 'deleted':
-                new_hrn = plslice_to_slice(slice['name'])
-                existing = cnx.query("SELECT * FROM "+tablename+" WHERE hrn = '"+new_hrn+"'; ").dictresult()
-                if len(existing) > 0:
-                    new_hrn = new_hrn+'-'+str(slice['slice_id'])
-                cnx.query("INSERT INTO "+tablename+"(hrn,type,wrapperurl,pointer) VALUES('"+new_hrn+"','slice','local',"+str(slice['slice_id'])+")")
-                
-    if type == 'component': #component registry
-        #populate node records
-        querystr = "SELECT node_id, hostname FROM nodes WHERE site_id = "+str(site_id)
-        nodes = cnx.query(querystr).dictresult()
-        for node in nodes:
-            new_hrn = plnode_to_node(node['hostname'], 0)
-            existing = cnx.query("SELECT * FROM "+tablename+" WHERE hrn = '"+new_hrn+"'; ").dictresult()
-            if len(existing) > 0:
-                new_hrn = plnode_to_node(node['hostname'], 1)
-                existing = cnx.query("SELECT * FROM "+tablename+" WHERE hrn = '"+new_hrn+"'; ").dictresult()
-                if len(existing) > 0:
-                    new_hrn = plnode_to_node(node['hostname'], 2)
-            cnx.query("INSERT INTO "+tablename+"(hrn,type,wrapperurl,pointer) VALUES('"+new_hrn+"','node','local',"+str(node['node_id'])+")")
-        
index dfa8d1b..2d6d7ac 100644 (file)
@@ -8,13 +8,37 @@ import report
 from gid import *
 
 ##
-# GeniRecord is a tuple (Name, GID, Type, Info)
-#    info is comprised of the following sub-fields
+# The GeniRecord class implements a Geni Record. A GeniRecord is a tuple
+# (Name, GID, Type, Info).
+#
+# Name specifies the HRN of the object
+# GID is the GID of the object
+# Type is user | sa | ma | slice | component
+#
+# Info is comprised of the following sub-fields
 #        pointer = a pointer to the record in the PL database
 #        pl_info = planetlab-specific info (when talking to client)
 #        geni_info = geni-specific info (when talking to client)
+#
+# The pointer is interpreted depending on the type of the record. For example,
+# if the type=="user", then pointer is assumed to be a person_id that indexes
+# into the persons table.
+#
+# A given HRN may have more than one record, provided that the records are
+# of different types. For example, planetlab.us.arizona may have both an SA
+# and a MA record, but cannot have two SA records.
 
 class GeniRecord():
+
+    ##
+    # Create a Geni Record
+    #
+    # @param name if !=None, assign the name of the record
+    # @param gid if !=None, assign the gid of the record
+    # @param type one of user | sa | ma | slice | component
+    # @param pointer is a pointer to a PLC record
+    # @param dict if !=None, then fill in this record from the dictionary
+
     def __init__(self, name=None, gid=None, type=None, pointer=None, dict=None):
         self.dirty = True
         self.pl_info = None
@@ -37,10 +61,20 @@ class GeniRecord():
             if "geni_info" in dict:
                self.set_geni_info(dict["geni_info"])
 
+    ##
+    # Set the name of the record
+    #
+    # @param name is a string containing the HRN
+
     def set_name(self, name):
         self.name = name
         self.dirty = True
 
+    ##
+    # Set the GID of the record
+    #
+    # @param gid is a GID object or the string representation of a GID object
+
     def set_gid(self, gid):
         if isinstance(gid, str):
             self.gid = gid
@@ -48,53 +82,109 @@ class GeniRecord():
             self.gid = gid.save_to_string(save_parents=True)
         self.dirty = True
 
+    ##
+    # Set the type of the record
+    #
+    # @param type is a string: user | sa | ma | slice | component
+
     def set_type(self, type):
         self.type = type
         self.dirty = True
 
+    ##
+    # Set the pointer of the record
+    #
+    # @param pointer is an integer containing the ID of a PLC record
+
     def set_pointer(self, pointer):
         self.pointer = pointer
         self.dirty = True
 
+    ##
+    # Set the PLC info of the record
+    #
+    # @param pl_info is a dictionary containing planetlab info
+
     def set_pl_info(self, pl_info):
         self.pl_info = pl_info
         self.dirty = True
 
+    ##
+    # Set the geni info the record
+    #
+    # @param geni_info is a dictionary containing geni info
+
     def set_geni_info(self, geni_info):
         self.geni_info = geni_info
         self.dirty = True
 
+    ##
+    # Return the pl_info of the record, or an empty dictionary if none exists
+
     def get_pl_info(self):
         if self.pl_info:
             return self.pl_info
         else:
             return {}
 
+    ##
+    # Return the geni_info of the record, or an empty dictionary if none exists
+
     def get_geni_info(self):
         if self.geni_info:
             return self.geni_info
         else:
             return {}
 
+    ##
+    # Return the name (HRN) of the record
+
     def get_name(self):
         return self.name
 
+    ##
+    # Return the type of the record
+
     def get_type(self):
         return self.type
 
+    ##
+    # Return the pointer of the record. The pointer is an integer that may be
+    # used to look up the record in the PLC database. The evaluation of pointer
+    # depends on the type of the record
+
     def get_pointer(self):
         return self.pointer
 
-    # TODO: not the best name for the function, because we have things called gidObjects in the Cred
+    ##
+    # Return the GID of the record, in the form of a GID object
+    # TODO: not the best name for the function, because we have things called
+    # gidObjects in the Cred
+
     def get_gid_object(self):
         return GID(string=self.gid)
 
+    ##
+    # Return a key that uniquely identifies this record among all records in
+    # Geni. This key is used to uniquely identify the record in the Geni
+    # database.
+
     def get_key(self):
         return self.name + "#" + self.type
 
+    ##
+    # Returns a list of field names in this record. pl_info, geni_info are not
+    # included because they are not part of the record that is stored in the
+    # database, but are rather computed values from other entities
+
     def get_field_names(self):
         return ["name", "gid", "type", "pointer"]
 
+    ##
+    # Given a field name ("name", "gid", ...) return the value of that field.
+    #
+    # @param name is the name of field to be returned
+
     def get_field_value_string(self, fieldname):
         if fieldname == "key":
             val = self.get_key()
@@ -105,12 +195,20 @@ class GeniRecord():
         else:
             return str(val)
 
+    ##
+    # Given a list of field names, return a list of values for those fields.
+    #
+    # @param fieldnames is a list of field names
+
     def get_field_value_strings(self, fieldnames):
         strs = []
         for fieldname in fieldnames:
             strs.append(self.get_field_value_string(fieldname))
         return strs
 
+    ##
+    # Return the record in the form of a dictionary
+
     def as_dict(self):
         dict = {}
         names = self.get_field_names()
@@ -125,6 +223,11 @@ class GeniRecord():
 
         return dict
 
+    ##
+    # Dump the record to stdout
+    #
+    # @param dump_parents if true, then the parents of the GID will be dumped
+
     def dump(self, dump_parents=False):
         print "RECORD", self.name
         print "        hrn:", self.name
index ac5e0fc..92ab583 100644 (file)
@@ -1,10 +1,18 @@
-# rights.py
+##
+# This Module implements rights and lists of rights for the Geni wrapper. Rights
+# are implemented by two classes:
 #
-# support for privileges according to GENI specification
-
-# privilege_table:
+# Right - represents a single right
+#
+# RightList - represents a list of rights
 #
-# a list of priviliges and what operations are allowed per privilege
+# A right may allow several different operations. For example, the "info" right
+# allows "listslices", "listcomponentresources", etc.
+##
+
+##
+# privilege_table is a list of priviliges and what operations are allowed
+# per privilege.
 
 privilege_table = {"authority": ["*"],
                    "refresh": ["remove", "update"],
@@ -16,12 +24,24 @@ privilege_table = {"authority": ["*"],
                    "info": ["listslices", "listcomponentresources", "getsliceresources"],
                    "ma": ["*"]}
 
-# a "Right" is a single privilege.
+##
+# The Right class represents a single privilege.
 
 class Right:
+   ##
+   # Create a new right.
+   #
+   # @param kind is a string naming the right. For example "control"
+
    def __init__(self, kind):
       self.kind = kind
 
+   ##
+   # Test to see if this right object is allowed to perform an operation.
+   # Returns True if the operation is allowed, False otherwise.
+   #
+   # @param op_name is a string naming the operation. For example "listslices".
+
    def can_perform(self, op_name):
       allowed_ops = privilege_table.get(self.kind.lower(), None)
       if not allowed_ops:
@@ -33,6 +53,13 @@ class Right:
 
       return (op_name.lower() in allowed_ops)
 
+   ##
+   # Test to see if this right is a superset of a child right. A right is a
+   # superset if every operating that is allowed by the child is also allowed
+   # by this object.
+   #
+   # @param child is a Right object describing the child right
+
    def is_superset(self, child):
       my_allowed_ops = privilege_table.get(self.kind.lower(), None)
       child_allowed_ops = privilege_table.get(child.kind.lower(), None)
@@ -46,19 +73,33 @@ class Right:
 
       return True
 
-# a "RightList" is a list of privileges
+##
+# A RightList object represents a list of privileges.
 
 class RightList:
+    ##
+    # Create a new rightlist object, containing no rights.
+    #
+    # @param string if string!=None, load the rightlist from the string
+
     def __init__(self, string=None):
         self.rights = []
         if string:
             self.load_from_string(string)
 
+    ##
+    # Add a right to this list
+    #
+    # @param right is either a Right object or a string describing the right
+
     def add(self, right):
         if isinstance(right, str):
             right = Right(kind = right)
         self.rights.append(right)
 
+    ##
+    # Load the rightlist object from a string
+
     def load_from_string(self, string):
         self.rights = []
 
@@ -70,6 +111,10 @@ class RightList:
         for part in parts:
             self.rights.append(Right(part))
 
+    ##
+    # Save the rightlist object to a string. It is saved in the format of a
+    # comma-separated list.
+
     def save_to_string(self):
         right_names = []
         for right in self.rights:
@@ -77,12 +122,27 @@ class RightList:
 
         return ",".join(right_names)
 
+    ##
+    # Check to see if some right in this list allows an operation. This is
+    # done by evaluating the can_perform function of each operation in the
+    # list.
+    #
+    # @param op_name is an operation to check, for example "listslices"
+
     def can_perform(self, op_name):
         for right in self.rights:
             if right.can_perform(op_name):
                 return True
         return False
 
+    ##
+    # Check to see if all of the rights in this rightlist are a superset
+    # of all the rights in a child rightlist. A rightlist is a superset
+    # if there is no operation in the child rightlist that cannot be
+    # performed in the parent rightlist.
+    #
+    # @param child is a rightlist object describing the child
+
     def is_superset(self, child):
         for child_right in child.rights:
             allowed = False
diff --git a/util/sec/certgen.py b/util/sec/certgen.py
deleted file mode 100755 (executable)
index d969f27..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# certgen.py
-#
-# Copyright (C) Martin Sjogren and AB Strakt 2001, All rights reserved
-#
-# $Id: certgen.py,v 1.2 2004/07/22 12:01:25 martin Exp $
-#
-"""
-Certificate generation and validation module.
-"""
-
-from OpenSSL import crypto
-import time, calendar, datetime
-
-TYPE_RSA = crypto.TYPE_RSA
-TYPE_DSA = crypto.TYPE_DSA
-
-def createKeyPair(type, bits):
-    """
-    Create a public/private key pair.
-
-    Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
-               bits - Number of bits to use in the key
-    Returns:   The public/private key pair in a PKey object
-    """
-    pkey = crypto.PKey()
-    pkey.generate_key(type, bits)
-    return pkey
-
-def createCertRequest(pkey, name, digest="md5"):
-    """
-    Create a certificate request.
-
-    Arguments: pkey   - The key to associate with the request
-               digest - Digestion method to use for signing, default is md5
-               **name - The name of the subject of the request, possible
-                        arguments are:
-                          C     - Country name
-                          ST    - State or province name
-                          L     - Locality name
-                          O     - Organization name
-                          OU    - Organizational unit name
-                          CN    - Common name
-                          emailAddress - E-mail address
-    Returns:   The certificate request in an X509Req object
-    """
-    req = crypto.X509Req()
-    subj = req.get_subject()
-    for (key,value) in name.items():
-        setattr(subj, key, value)
-    req.set_pubkey(pkey)
-    req.sign(pkey, digest)
-    return req
-
-def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), extensions=[], digest="md5"):
-    """
-    Generate a certificate given a certificate request.
-
-    Arguments: req        - Certificate reqeust to use
-               issuerCert - The certificate of the issuer
-               issuerKey  - The private key of the issuer
-               serial     - Serial number for the certificate
-               notBefore  - Timestamp (relative to now) when the certificate
-                            starts being valid
-               notAfter   - Timestamp (relative to now) when the certificate
-                            stops being valid
-               digest     - Digest method to use for signing, default is md5
-    Returns:   The signed certificate in an X509 object
-    """
-    cert = crypto.X509()
-    cert.set_serial_number(serial)
-    cert.gmtime_adj_notBefore(notBefore)
-    cert.gmtime_adj_notAfter(notAfter)
-    cert.set_issuer(issuerCert.get_subject())
-    cert.set_subject(req.get_subject())
-    cert.set_pubkey(req.get_pubkey())
-    if extensions:
-        extList = []
-        for name, critical, value in extensions:
-            ext = crypto.X509Extension (name, critical, value)
-            extList.append(ext)
-        cert.add_extensions(extList)
-    cert.sign(issuerKey, digest)
-    return cert
-
-
-#checks if a certificate is valid in terms of validity periods    
-def check_valid(usercert):
-    """
-    Method that ensures the issuer cert has
-    valid, not_before and not_after fields
-    """
-    valid = True
-    before_time = usercert.get_not_before()
-    after_time = usercert.get_not_after()
-    before_tuple = time.strptime(str(before_time), "%b %d %H:%M:%S %Y %Z")
-    after_tuple = time.strptime(str(after_time), "%b %d %H:%M:%S %Y %Z")
-    starts =  datetime.timedelta(seconds=calendar.timegm(before_tuple))
-    expires = datetime.timedelta(seconds=calendar.timegm(after_tuple))
-    now = datetime.timedelta(seconds=time.time())
-    time_delta = expires - now
-    
-    #cert has expired
-    if time_delta.days < 0:
-        valid = False
-    #cert is not yet valid
-    time_delta = now - starts
-    if time_delta.days < 0:   
-        valid = False
-
-    return valid
diff --git a/util/sec/certgen.pyc b/util/sec/certgen.pyc
deleted file mode 100644 (file)
index 4bfb1ae..0000000
Binary files a/util/sec/certgen.pyc and /dev/null differ
diff --git a/util/sec/certgen2.py b/util/sec/certgen2.py
deleted file mode 100755 (executable)
index 4fb5a4d..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Certificate generation module.
-"""
-
-from OpenSSL     import crypto
-from os          import chmod, remove
-from os.path     import join
-
-from myap.tools  import execute_cmd
-from myap.config import config
-
-TYPE_RSA = crypto.TYPE_RSA
-TYPE_DSA = crypto.TYPE_DSA
-
-YEAR = 60*60*24*365
-
-X509Attr    = ( 'C', 'ST', 'L', 'O', 'OU', 'CN', 'emailAddress' )
-X509WinAttr = { 'C'            : 'C',
-                'ST'           : 'S',
-                'L'            : 'L',
-                'O'            : 'O',
-                'OU'           : 'OU',
-                'CN'           : 'CN',
-                'emailAddress' : 'E' }
-
-def createKeyPair(type, bits):
-    """
-    Create a public/private key pair.
-
-    Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
-               bits - Number of bits to use in the key
-
-    Returns:   The public/private key pair in a PKey object
-    """
-
-    pkey = crypto.PKey()
-    pkey.generate_key(type, bits)
-
-    return pkey
-
-def createCertRequest(pkey, subject, digest='md5'):
-    """
-    Create a certificate request.
-
-    Arguments: pkey    - The key to associate with the request
-               subject - A dictionary with the subject of the request, possible
-                         key,value pairs are:
-                           C            - Country name
-                           ST           - State or province name
-                           L            - Locality name
-                           O            - Organization name
-                           OU           - Organizational unit name
-                           CN           - Common name
-                           emailAddress - E-mail address
-               digest  - Digestion method to use for signing, default is md5
-
-    Returns:   The certificate request in an X509Req object
-    """
-
-    req  = crypto.X509Req()
-    subj = req.get_subject()
-
-    # Storing attributes in the correct order
-    for attr in X509Attr:
-        if subject.has_key(attr):
-            setattr(subj, attr, subject[attr])
-
-    req.set_pubkey(pkey)
-    req.sign(pkey, digest)
-
-    return req
-
-def createCertificate(req, (issuerKey, issuerCert), serial, (notBefore, notAfter), extensions=[], digest='md5'):
-    """
-    Generate a certificate given a certificate request.
-
-    Arguments: req        - Certificate reqeust to use
-               issuerCert - The certificate of the issuer
-               issuerKey  - The private key of the issuer
-               serial     - Serial number for the certificate
-               notBefore  - Timestamp (relative to now) when the certificate
-                            starts being valid
-               notAfter   - Timestamp (relative to now) when the certificate
-                            stops being valid
-               digest     - Digest method to use for signing, default is md5
-               isca       - The certificate is a CA
-
-    Returns:   The signed certificate in an X509 object
-    """
-
-    cert = crypto.X509()
-    cert.set_version(2)
-
-    if extensions:
-        X509Extensions = []
-        for name, critical, value in extensions:
-            X509Extensions.append(crypto.X509Extension(name, critical, value))
-
-        cert.add_extensions(X509Extensions)
-
-    cert.set_serial_number(serial)
-    cert.gmtime_adj_notBefore(notBefore)
-    cert.gmtime_adj_notAfter(notAfter)
-    cert.set_issuer(issuerCert.get_subject())
-    cert.set_subject(req.get_subject())
-    cert.set_pubkey(req.get_pubkey())
-    cert.sign(issuerKey, digest)
-
-    return cert
-
-def createSignedCertificate(subject, serial, extensions=[], type=TYPE_RSA, bits=2048, cipher='DES-EDE3-CBC', passphrase='', years=5, capkey='', cacert='', capassphrase=''):
-    """
-    Generate a Signed Certificate.
-
-    Arguments: subject      - The subject of the request, see createCertRequest()
-               type         - (optional) Key type, see createKeyPair()
-               bits         - (optional) Number of bits to use in the key
-               cipher       - (optional) if encrypted PEM format, the cipher to use, see dump_privatekey()
-               passphrase   - (optional) if encrypted PEM format, the passphrase to use, see dump_privatekey()
-               years        - (optional) Number of years to use for validity, see X509()
-               capkey       - (optional) CA's private key (PEM formated string)
-               cacert       - (optional) CA's certificate (PEM formated string)
-               capassphrase - (optional) if CA private key is in encrypted PEM format,
-                              the passphrase to use, see load_privatekey()
-               
-    Returns:   Two PEM formated strings containing private key and signed certificate
-    """
-
-    pkey = createKeyPair(type, bits)
-    req  = createCertRequest(pkey, subject)
-
-    if capkey and cacert:
-        # Certificate will be signed by an Autority
-        capkey = crypto.load_privatekey(crypto.FILETYPE_PEM,  capkey, capassphrase)
-        cacert = crypto.load_certificate(crypto.FILETYPE_PEM, cacert)
-    else:
-        # Self signed certificate
-        capkey = pkey
-        cacert = req
-
-    cert = createCertificate(req, (capkey, cacert), serial, (0, years*YEAR), extensions=extensions)
-
-    if passphrase:
-        pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey, cipher, passphrase)
-    else:
-        pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
-
-    cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
-
-    return (pkey, cert)
-
-def getSubject(cert, for_win=False):
-
-    cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
-    subj = cert.get_subject()
-
-    subject = ''
-    for attr in X509Attr:
-        value = getattr(subj, attr)
-        if value:
-            if for_win:
-                # Converting Attr to Windows Attr
-                attr = X509WinAttr[attr]
-            subject += '%s=%s, ' % (attr, value)
-
-    subject = subject[:-2]
-
-    return subject
-
-def convertPemToDer(pkey, cert, cipher='DES-EDE3-CBC', passphrase=''):
-    """
-    Convert two PEM formated strings (pkey, cert) onto two DER formated strings.
-
-    Arguments: pkey       - private key (PEM formated string)
-               cert       - certificate (PEM formated string)
-               cipher     - (optional) if encrypted PEM format, the cipher to use, see dump_privatekey()
-               passphrase - (optional) if encrypted PEM format, the passphrase to use, see dump_privatekey()
-
-    Returns:   Two DER formated strings containing private key and signed certificate
-    """
-
-    pkey = crypto.load_privatekey(crypto.FILETYPE_PEM,  pkey, passphrase)
-    cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
-    
-    if passphrase:
-        pkey = crypto.dump_privatekey(crypto.FILETYPE_ASN1, pkey, cipher, passphrase)
-    else:
-        pkey = crypto.dump_privatekey(crypto.FILETYPE_ASN1, pkey)
-
-    cert = crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)
-
-    return (pkey, cert)
-
-def convertDerToPem(pkey, cert, cipher='DES-EDE3-CBC', passphrase=''):
-    """
-    Convert two DER formated strings (pkey, cert) onto two PEM formated strings.
-
-    Arguments: pkey       - private key (DER formated string)
-               cert       - certificate (DER formated string)
-               cipher     - (optional) if encrypted DER format, the cipher to use, see dump_privatekey()
-               passphrase - (optional) if encrypted DER format, the passphrase to use, see dump_privatekey()
-
-    Returns:   Two PEM formated strings containing private key and signed certificate
-    """
-
-    pkey = crypto.load_privatekey(crypto.FILETYPE_ASN1,  pkey, passphrase)
-    cert = crypto.load_certificate(crypto.FILETYPE_ASN1, cert)
-    
-    if passphrase:
-        pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey, cipher, passphrase)
-    else:
-        pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
-
-    cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
-
-    return (pkey, cert)
-
-def dump_pkcs12(pkey, cert, cacert='', passphrase=''):
-    """
-
-    """
-
-    # Storing all the params to a temp file
-    temp_file = '/tmp/pkcs12'
-
-    pkcs12 = pkey + cert + cacert
-
-    f = open(temp_file, 'w')
-    f.write(pkcs12)
-    f.close()
-    chmod(temp_file, 0600)
-
-    # Create pkcs12 file with openssl
-    cmd = 'openssl pkcs12 -export -in %s -passout pass:"%s"' % (temp_file, passphrase)
-
-    exitcode, pkcs12 = execute_cmd(cmd)
-    remove(temp_file)
-    
-    if exitcode:
-        return pkcs12
-
-    return None
-
-def newCertificate(db, ip):
-
-    serial = db.get_last_serial_cert()
-    ca     = db.get_certificate(serial=0)
-
-    # Creating the certificate for the ip
-    serial       += 1
-    subject       = config['SSL_DEFAULT']
-    subject['CN'] = ip
-    extensions    = (('nsCertType',       False, 'client'),
-                     ('keyUsage',         False, 'dataEncipherment'),
-                     ('extendedKeyUsage', False, 'clientAuth,1.3.6.1.4.1.311.10.3.4.1'))
-    pkey, cert = createSignedCertificate(subject, serial, extensions=extensions, bits=1024, capkey=ca['private_key'], cacert=ca['certificate'], capassphrase=config['SSL_CA_PASS'])
-
-    # Adding it to the database
-    db_cert = {}
-    db_cert['serial']      = serial
-    db_cert['private_key'] = pkey
-    db_cert['certificate'] = cert
-
-    return db.set_certificate(db_cert)
-
-def getPKCS12(db, reservation_id):
-
-    ca          = db.get_certificate(serial=0)
-    reservation = db.get_reservation(reservation_id=reservation_id)
-    certificate = db.get_certificate(certificate_id=reservation['certificate_id'])
-
-    pkcs12 = dump_pkcs12(certificate['private_key'], certificate['certificate'], ca['certificate'])
-
-    return pkcs12
-    
-def revokeCertificate(db, certificate_id):
-
-    return True
-
-def init(db):
-
-    db.delete_certificates()
-
-    # Creating the CA
-    serial     = 0
-    subject    = config['SSL_DEFAULT']
-    extensions = (('basicConstraints', True,  'CA:true'),
-                  ('nsCertType',       False, 'objCA,sslCA,objsign,client,server'),
-                  ('keyUsage',         False, 'keyCertSign,cRLSign,nonRepudiation,keyEncipherment,dataEncipherment'),
-                  ('extendedKeyUsage', False, 'clientAuth,serverAuth,1.3.6.1.4.1.311.10.3.4.1')) # 1.3.6.1.4.1.311.10.3.4.1 is for VPN
-
-    capkey, cacert = createSignedCertificate(subject, serial, extensions=extensions, passphrase=config['SSL_CA_PASS'])
-
-    # Adding it to the database
-    db_cert = {}
-    db_cert['serial']      = serial
-    db_cert['private_key'] = capkey
-    db_cert['certificate'] = cacert
-    if not db.set_certificate(db_cert):
-        return False
-
-    # Creating the certificate for the WebServer
-    serial       += 1
-    subject['CN'] = config['SERVER_NAME']
-    extensions    = (('nsCertType',       False, 'server'),
-                     ('keyUsage',         False, 'keyEncipherment'),
-                     ('extendedKeyUsage', False, 'serverAuth'))
-
-    pkey, cert = createSignedCertificate(subject, serial, extensions=extensions, bits=1024, capkey=capkey, cacert=cacert, capassphrase=config['SSL_CA_PASS'])
-
-    # Adding it to the database
-    db_cert = {}
-    db_cert['serial']      = serial
-    db_cert['private_key'] = pkey
-    db_cert['certificate'] = cert
-    if not db.set_certificate(db_cert):
-        return False
-
-    try:
-        f = open(config['MYAP_HTTPD_PKEY'], 'w')
-        f.write(pkey)
-        f.close()
-        chmod(config['MYAP_HTTPD_PKEY'], 0600)
-    
-        f = open(config['MYAP_HTTPD_CERT'], 'w')
-        f.write(cert)
-        f.close()
-
-    except:
-        return False
-
-    # Creating the certificate for Racoon
-    serial       += 1
-    subject['CN'] = 'Racoon Server'
-    extensions    = (('nsCertType',       False, 'client,server'),
-                     ('keyUsage',         False, 'keyEncipherment'),
-                     ('extendedKeyUsage', False, 'clientAuth,serverAuth,1.3.6.1.4.1.311.10.3.4.1'))
-
-    pkey, cert = createSignedCertificate(subject, serial, extensions=extensions, bits=1024, capkey=capkey, cacert=cacert, capassphrase=config['SSL_CA_PASS'])
-
-    # Adding it to the database
-    db_cert = {}
-    db_cert['serial']      = serial
-    db_cert['private_key'] = pkey
-    db_cert['certificate'] = cert
-    if not db.set_certificate(db_cert):
-        return False
-
-    try:
-        pkey_file = join(config['SSL_TOP_DIR'], config['RACOON_PKEY'])
-        cert_file = join(config['SSL_TOP_DIR'], config['RACOON_CERT'])
-
-        f = open(pkey_file, 'w')
-        f.write(pkey)
-        f.close()
-        chmod(pkey_file, 0600)
-    
-        f = open(cert_file, 'w')
-        f.write(cert)
-        f.close()
-
-    except:
-        return False
-
-    return True
diff --git a/util/sec/certgen_m2crypto.py b/util/sec/certgen_m2crypto.py
deleted file mode 100755 (executable)
index 220b255..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#certificate generation functions
-
-from M2Crypto import X509
-from M2Crypto import EVP
-
-def createKeyPair(type, bits):
-    """
-    Create a public/private key pair.
-
-    Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
-               bits - Number of bits to use in the key
-    Returns:   The public/private key pair in a PKey object
-    """
-    
-    
-    
-    
-
-
-
diff --git a/util/sec/certs/den.py b/util/sec/certs/den.py
deleted file mode 100644 (file)
index 33cae57..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-import sys
-from OpenSSL import crypto
-from M2Crypto import X509
-sys.path.append('../')
-sys.path.append('../..')
-from sec import *
-
-
-##osaka2 = X509.load_cert_string(crypto.dump_certificate(crypto.FILETYPE_PEM, osaka_acc))
-##usersoner2 = X509.load_cert_string(crypto.dump_certificate(crypto.FILETYPE_PEM, usersoner_acc))
-##
-##t1 = osaka2.as_text()
-##t2 = usersoner2.as_text()
-##
-##res = usersoner2.verify(osaka2.get_pubkey()) 
-##
-##print res
-
-#pl_pem = X509.load_cert('usersoner.cert')
-#pkey = pl_pem.get_pubkey().as_pem(cipher=None)
-
-#from pg import DB
-
-#dbname = 'plDB'
-#address = 'localhost'
-#port = 5433
-#user = 'postgres'
-#password = '111'
-#cnx = DB(dbname, address, port=port, user=user, passwd=password)
-#cnx.query("UPDATE planetlab$jp$osaka_sr SET pubkey = '"+pkey+"' WHERE hrn = 'usersoner'")
-
-#print pkey
-
-
-planetlab_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open('planetlab.cert').read())
-planetlab_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open('planetlab.pkey').read())
-planetlab_acc = create_acc(planetlab_cert, planetlab_pkey, planetlab_cert.get_pubkey(), 'planetlab', '28698598650165084658569185050284587399', 3)
-ac1 = crypto.dump_certificate(crypto.FILETYPE_PEM, planetlab_acc)
-open('planetlab_acc_file', 'w').write(ac1)
-
-##
-##res = c1_pem2.verify(c3_pem2.get_pubkey()) 
diff --git a/util/sec/certs/gen.py b/util/sec/certs/gen.py
deleted file mode 100644 (file)
index 4db2307..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-import sys
-from OpenSSL import crypto
-sys.path.append('../')
-sys.path.append('../..')
-from sec import *
-
-#id certificates
-
-create_self_cert('planetlab')
-create_self_cert('jp')
-create_self_cert('osaka')
-create_self_cert('usersoner')
-
-planetlab_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open('planetlab.cert').read())
-jp_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open('jp.cert').read())
-osaka_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open('osaka.cert').read())
-usersoner_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open('usersoner.cert').read())
-
-planetlab_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open('planetlab.pkey').read())
-jp_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open('jp.pkey').read())
-osaka_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open('osaka.pkey').read())
-usersoner_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open('usersoner.pkey').read())
-
-#accounting certificates
-
-planetlab_acc = create_acc(planetlab_cert, planetlab_pkey, planetlab_cert.get_pubkey(), 'planetlab', '77059b82-e826-11dc-9dc2-001ec2091968')
-jp_acc = create_acc(planetlab_cert, planetlab_pkey, jp_cert.get_pubkey(), 'planetlab.jp', '3fd66a4c-d574-4aa0-9ddd-3904af595bd2')
-osaka_acc = create_acc(jp_cert, jp_pkey, osaka_cert.get_pubkey(), 'planetlab.jp.osaka', '05b3c29b-0dae-4a95-b92b-0e01548f61e0')
-usersoner_acc = create_acc(osaka_cert, osaka_pkey, usersoner_cert.get_pubkey(), 'planetlab.jp.osaka.usersoner', '220828220198687580431599291716859620971')
-
-#credential certificates
-
-planetlab_cred = create_cred(planetlab_cert, planetlab_pkey, planetlab_cert.get_pubkey(), 'Registry credentials', '(0-0)(1-0)(2-0)(3-0)(4-0)(5-0)(6-0)(7-0)(8-0)(9-0)#0:reg:planetlab')
-jp_cred = create_cred(planetlab_cert, planetlab_pkey, jp_cert.get_pubkey(), 'Registry credentials', '(2-0)(4-0)(6-0)(7-0)(8-0)(9-0)(0-1)(1-1)(2-1)(3-1)(4-1)(5-1)(6-1)(7-1)(8-1)(9-1)#0:reg:planetlab#1:reg:planetlab.jp')
-osaka_cred = create_cred(jp_cert, jp_pkey, osaka_cert.get_pubkey(), 'Registry credentials', '(2-0)(4-0)(6-0)(7-0)(8-0)(9-0)(0-1)(1-1)(2-1)(3-1)(4-1)(5-1)(6-1)(7-1)(8-1)(9-1)#0:reg:planetlab.jp#1:reg:planetlab.jp.osaka')
-usersoner_cred = create_cred(osaka_cert, osaka_pkey, usersoner_cert.get_pubkey(), 'Registry credentials', '(0-0)(1-0)(2-0)(3-0)(4-0)(5-0)(6-0)(7-0)(8-0)(9-0)#0:reg:planetlab.jp.osaka')
-
-#acc and cred files
-
-ac1 = crypto.dump_certificate(crypto.FILETYPE_PEM, planetlab_acc)
-ac2 = crypto.dump_certificate(crypto.FILETYPE_PEM, jp_acc)
-ac3 = crypto.dump_certificate(crypto.FILETYPE_PEM, osaka_acc)
-ac4 = crypto.dump_certificate(crypto.FILETYPE_PEM, usersoner_acc)
-#open('planetlab_acc_file', 'w').write(ac1)
-#open('jp_acc_file', 'w').write(ac2+ac1)
-open('osaka_acc_file', 'w').write(ac3+ac2+ac1)
-open('usersoner_acc_file', 'w').write(ac4+ac3+ac2+ac1)
-
-cred1 = crypto.dump_certificate(crypto.FILETYPE_PEM, planetlab_cred)
-cred2 = crypto.dump_certificate(crypto.FILETYPE_PEM, jp_cred)
-cred3 = crypto.dump_certificate(crypto.FILETYPE_PEM, osaka_cred)
-cred4 = crypto.dump_certificate(crypto.FILETYPE_PEM, usersoner_cred)
-#open('planetlab_cred_file', 'w').write(cred1)
-#open('jp_cred_file', 'w').write(cred2+cred1)
-open('osaka_cred_file', 'w').write(cred3+cred2+cred1)
-open('usersoner_cred_file', 'w').write(cred4+cred3+cred2+cred1)
-
diff --git a/util/sec/certs/jp.cert b/util/sec/certs/jp.cert
deleted file mode 100644 (file)
index 5e8418d..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBiDCB8gIBADANBgkqhkiG9w0BAQQFADANMQswCQYDVQQDEwJqcDAeFw0wODAz
-MDMwMzQ0NTBaFw0xMzAzMDIwMzQ0NTBaMA0xCzAJBgNVBAMTAmpwMIGfMA0GCSqG
-SIb3DQEBAQUAA4GNADCBiQKBgQC5fCqy5k2JzHNLBOBf2Ptw25iyMBNu787yf0S/
-NrI9iesdV7cD2C0Jwrrn2nuur8J8CKR4gb1EKm3U6gSMnPSHM5dZ+XQN4RuGWciu
-nrVQ3RdEPccvVufrzd1sB8OFeT92DPlHT85GZ4WoijH3lupaXBq9IpiQ2sC74WID
-kA28ZwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAFiJpvDxCK7MdCMaedh8mN6i4FVE
-GKk/nES7cc5MxH3F3nvYuluew0A7l83tYwq98E9yZz593mjQHxyIAGsNFaVALkWx
-ZEmK7afYTnXInTLRRZv00PuhRp+12zQ7gY2fkjYVMpgGdPB/n0NrP9pirBzEmht+
-FIudlteVKYY+VVm2
------END CERTIFICATE-----
diff --git a/util/sec/certs/jp.pkey b/util/sec/certs/jp.pkey
deleted file mode 100644 (file)
index d3273ff..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQC5fCqy5k2JzHNLBOBf2Ptw25iyMBNu787yf0S/NrI9iesdV7cD
-2C0Jwrrn2nuur8J8CKR4gb1EKm3U6gSMnPSHM5dZ+XQN4RuGWciunrVQ3RdEPccv
-Vufrzd1sB8OFeT92DPlHT85GZ4WoijH3lupaXBq9IpiQ2sC74WIDkA28ZwIDAQAB
-AoGBALdJMwhE+ynHlcXzs6QCzbPfyyuIxitBXMXTbSNl8QtOVb5RBtANtbOHcRna
-k40ysIPQJnXN/jB1nMJf3M716cpgOeBwECVLkGVpq7zTYsWdeh7lTEOh/aUbDgKZ
-nOnGqogKGaiQ92Fhs7ImyCHyb6e8SdFFHi1BAGGXQ5P0QXHBAkEA6fWvv/5fn7Jy
-2UyKMqO6LxGL08nzIzJNLU36WCTFfuFlXeQpoSZ7QqDCkZUY3zHNo4p5nBSzju4+
-lmczfIWhiwJBAMr1b317SeV8viOpn8rpfB0/IhLZ8EdPwsVsEMpIDcqpJZHCiLBl
-HrEQtu+PJGBN93gznR8rJgEKK3tYQBc99BUCQQDgwpbE66sR0G1lNJLPc1s6PLEI
-Fcru1TQvgeovI6RX8FFhkgAsQLvJlodVNNdgFIhpxG5v87NMbLTT6PEdf4NhAkAE
-QIIWcefJbASbwKj9WkjkX/c5x+EVzWD6O9paMoo/ba3A0P+GGog7E2uRt0D+14NQ
-vFwVVBUWvnzMt7uYAQ9FAkA7XNbDWBeW/7zIt9yrTx+dM+xN2fftV7RxMB1pSSEP
-Ugsm2nyCj6ZuEhHn8PjB9+bNfK/PrGC/qjTDyPH+zvYp
------END RSA PRIVATE KEY-----
diff --git a/util/sec/certs/planetlab.cert b/util/sec/certs/planetlab.cert
deleted file mode 100644 (file)
index 4fd627f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBlzCCAQACAQAwDQYJKoZIhvcNAQEEBQAwFDESMBAGA1UEAxMJcGxhbmV0bGFi
-MB4XDTA4MDMyMTIyMDE0MVoXDTEzMDMyMDIyMDE0MVowFDESMBAGA1UEAxMJcGxh
-bmV0bGFiMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4nsgYgX1n8mUs0dPb
-krTFtThw5ULBPr45s7Al0tsaG80I/UpjZG07Q4QnaEfFu/2xWBsAC0S5HopbSS3w
-Ykr+OkQO4DNV0+RwRhGqHamhnjSl7Ar9svHzzgIFujl9vQdqoWzWXzW2eDkbtqb8
-elDnit1bwCC2yrRNoivuAFFSsQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAKWSfdwa
-bMWqViR5/aRR8tD6mQ7jwhKA6glr7vSCWvdKsHhKSZd2NrpCnyP5ew1c4E0XKwU0
-TPLwLDsIMUcy0lSojjAETy7mrIHlqPxCL8WP9Wp7U9No8jVbe1E/i89a/qahhL7v
-fvA5Nb91VeJXaE2hr7bG6so6aG8WIMm90d4A
------END CERTIFICATE-----
diff --git a/util/sec/certs/planetlab.pkey b/util/sec/certs/planetlab.pkey
deleted file mode 100644 (file)
index c292395..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQC4nsgYgX1n8mUs0dPbkrTFtThw5ULBPr45s7Al0tsaG80I/Upj
-ZG07Q4QnaEfFu/2xWBsAC0S5HopbSS3wYkr+OkQO4DNV0+RwRhGqHamhnjSl7Ar9
-svHzzgIFujl9vQdqoWzWXzW2eDkbtqb8elDnit1bwCC2yrRNoivuAFFSsQIDAQAB
-AoGAR6gxZ/mSkC7wACZtAXN+wKInBwKlF1ZgBQtuWi/uJMMXoN6W6d8H2pHJEHaU
-LPZbcGMPD8RP5z4oW2ga8YtlKYD2tKqulXm07yMIpbLs4+3FgFHzN4H5lCb511Zq
-EdVKtXAxp2X+H0wGB4g26UqvSp8/Kp4x2u63X48+5aRjODECQQDZ5WGrJFDLmHWt
-6NcvYYiJJ0jGwve8iRsVBOqT8wiAQ+7QFfnlnrwLxOsm2qCZokFrFmx0YnYmZ27y
-uaAI9TydAkEA2Oe7op+wcN5Xpa19yGy4/mnsGfGbxkWucBWmMTiJbq0NtSYdbAnL
-4DUnG+0SdtpA5OoXBnUQs2nXcWq/YCDQJQJAZCEIdMDHcAerbDNnTxqex4gJ5WyK
-s1S94TbVJQ+1hFuzTmQK5f2/pBjlhoFI89CgBznStNjaOmOllFzAsd0f8QJBAJ80
-X/W6bkA6Am0ZzVQZ8SLTzjcwrpy2MpYUXdqM29r/bCtFIZ1WB222tdD6jm3sPmuH
-IoVb0XlOu5KEvpkpHH0CQHnzGFbx4gj5fGanVgyMjd6FY0vJO15vpsrmAeYDbVfT
-4FeaALZcN5oA6xaD5xxL2+tvw7j/oy9UtMQRrcKYmcM=
------END RSA PRIVATE KEY-----
diff --git a/util/sec/certs/usersoner.cert b/util/sec/certs/usersoner.cert
deleted file mode 100644 (file)
index 7197504..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBlzCCAQACAQAwDQYJKoZIhvcNAQEEBQAwFDESMBAGA1UEAxMJdXNlcnNvbmVy
-MB4XDTA4MDMwMzAzNDQ1MVoXDTEzMDMwMjAzNDQ1MVowFDESMBAGA1UEAxMJdXNl
-cnNvbmVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9ax+M8gWEr1PsgPJM
-KP8nHWRJBnevXxMLmpFfz8kzC2CY1PQ3VzGClyp6v3ryv/Tp9W+otE7M9SCMx+aG
-ibTRMJFnYag1VJyIywX72fDuMTlvS3SMz1NPsda7PzqhmyRiE8c5wlgQWSNktker
-/wmEN2qfIC+ufBVsslsehkpkQQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAGT7dqbw
-wHNi33eT33qneUdbfYWH+fDM2sTIdiQXYhcBEyXXWwHNlW46sq/aCol8uSNhEjbK
-rDzAfGsIqNAeBHBeuG5FgEqt0mOtglyjqQ82v6keayIOYIUJ3f7Vw7YorPyGs8x7
-SxYqbGOvuPHnItV507Orj/fQOXW1ZerYFhrk
------END CERTIFICATE-----
diff --git a/util/sec/sec.py b/util/sec/sec.py
deleted file mode 100644 (file)
index c035697..0000000
+++ /dev/null
@@ -1,663 +0,0 @@
-import os, sys
-from OpenSSL import crypto
-from M2Crypto import X509
-from M2Crypto import SSL
-sys.path.append('../')
-from certgen import *
-from util import *
-from db import *
-from tree import *
-
-CRED_GRANT_TIME = 3600000 #in seconds
-ACC_GRANT_TIME = 10000000
-TOP_LEVEL_CERTS_DIR = "trusted_certs"
-MAX_CERT_SIZE = 1024
-MAX_CERT_CHAIN = 9
-
-creds= ["","","","","","","","","","","","","","","","","","","","","","","","",""]
-creds[0] = "register"
-creds[1] = "remove"
-creds[2] = "remove_self"
-creds[3] = "update"
-creds[4] = "update_self"
-creds[5] = "lookup"
-creds[6] = "lookup_self"
-creds[7] = "list"
-creds[8] = "getCredential"
-creds[9] = "getAccounting"
-creds[10] = "getTicket"      # = embed privilege in the docs
-creds[11] = "splitTicket"
-creds[12] = "redeemTicket"
-creds[13] = "stop"
-creds[14] = "start"
-creds[15] = "delete"
-creds[16] = "listSlices"
-creds[17] = "getStatus"
-creds[18] = "getSlice"
-creds[19] = "refresh"
-creds[20] = "delegate"
-creds[21] = "instantiate"
-creds[22] = "bind"
-creds[23] = "control"
-
-class PeerInfo :
-    def __init__(self):
-        self.cert = None
-        self.acc = Accounting()   #accounting information
-        self.cred = Credential()  #credential information
-
-#info_certs looks like: [{'hrn':None, 'uuid':0}]
-class Accounting:
-    def __init__(self):
-        self.info_certs = []
-        self.cert_chain = []
-    def get_hrn(self):
-        return self.info_certs[0]['hrn']
-    def get_uuid(self):
-        return self.info_certs[0]['uuid']
-
-#info_certs looks like: [{'operation_set':None, 'on_interfaces':None}]
-#operation_set looks like: [0:['register','update','update_self',..], 1:['getTicket', 'splitTicket',..],..]
-#on_interfaces looks like: [{'lbl':0, 'name':'planetlab.jp.jaist', 'type':'registry'},..{}]
-class Credential: 
-    def __init__(self):
-        self.info_certs = [] #list of operations and list of sites on which operations can be performed
-        self.cert_chain = []
-    def get_cred(self):
-        return self.info_certs[0]
-        
-#type: 'accounting' or 'credential' 
-#folder: directory of that the certificate should reside
-#reg_type: 'slice' or 'component'
-#hrn: name of the object to get certificates for
-#server: the server instance to do operations calls with in the internal tree
-#internal_tree: tree for internal cert renewals
-#auth_addr: authority to ask for certificates
-#sec: security module to perform auth. protocol with the remote peer
-#return 0: no renewal done, 1: renewal done, None: error
-def renew_cert(type, folder, reg_type, hrn, server, internal_tree, auth_addr, sec):
-    #check if necessary to renew
-    if type == 'accounting':
-        fname = folder+'/acc_file'
-    else:
-        fname = folder+'/cred_file'
-    if os.path.exists(fname) and is_valid_chain(fname):
-        return 0
-    else:
-        parent_hrn = obtain_authority(hrn)
-        hrn_suffix = get_leaf(hrn)
-        id_file = folder+'/'+hrn_suffix+'.cert'
-        #check the id file
-        if not os.path.exists(folder) or not os.path.exists(id_file):
-            print 'Id file for '+hrn+' does not exist.\n'
-            return None
-        #decide if remote call
-        remote = True
-        if internal_tree:
-            dbinfo = determine_dbinfo(parent_hrn, internal_tree)
-            if dbinfo:
-                remote = False
-        if not remote:
-            if type == 'accounting':
-                #obtain the accounting from parent, write to file
-                g = {"hrn":""}
-                g["hrn"] = parent_hrn
-                g['registry'] = reg_type
-                g["account_name"] = hrn 
-                p = {}
-                record = {'g_params':g, 'p_params':p}
-                dbinfo = determine_dbinfo(parent_hrn, internal_tree)
-                parentkeyinfo = internal_tree.determine_keyinfo(parent_hrn, server, type)
-                open(fname, 'w').write(server.getAccounting(record, dbinfo, parentkeyinfo, X509.load_cert(id_file)))
-            else:
-                #obtain the credential from parent, write to file
-                g = {"hrn":""}
-                g["hrn"] = parent_hrn
-                if reg_type == 'slice':
-                    g['cred_name'] = 'registry:slc'
-                else:
-                    g['cred_name'] = 'registry:comp'
-                p = {}
-                record = {'g_params':g, 'p_params':p}
-                dbinfo = determine_dbinfo(parent_hrn, internal_tree)
-                id = crypto.load_certificate(crypto.FILETYPE_PEM, open(id_file).read())
-                peerinfo = [hrn, id]
-                parentkeyinfo = internal_tree.determine_keyinfo(parent_hrn, server, type)
-                open(fname, 'w').write(server.getCredential(record, dbinfo, parentkeyinfo, peerinfo))
-        else: #if not local call
-            if obtain_authority(hrn) == '':  #we are at the root
-                id_key_file = folder+'/'+hrn_suffix+'.pkey'
-                id_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(id_file).read())
-                id_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open(id_key_file).read())
-                peer_cred_str = open(fname).read()
-                c_pem = X509.load_cert_string("-----BEGIN CERTIFICATE-----"+peer_cred_str.split("-----BEGIN CERTIFICATE-----")[1])
-                if type == 'accounting':
-                    cert_uuid = c_pem.get_ext("subjectAltName").get_value().split('http://')[1].split('#')[2].split('uuid:')[1]
-                    acc = create_acc(id_cert, id_pkey, id_cert.get_pubkey(), hrn, cert_uuid)
-                    open(fname, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, acc))
-                else:
-                    rights = c_pem.get_ext("subjectAltName").get_value().split('http://')[1].split('credential_set:')[1]
-                    cred = create_cred(id_cert, id_pkey, id_cert.get_pubkey(), 'Registry credentials', rights)
-                    open(fname, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cred))
-            else:
-                operation = ''                    
-                g = {"hrn":obtain_authority(hrn)}
-                if type == 'accounting':
-                    operation = "getAccounting";
-                    #geni parameters
-                    g['registry'] = reg_type
-                    g["account_name"] = hrn
-                else:
-                    operation = "getCredential"
-                    #geni parameters
-                    if reg_type == 'slice':
-                        g['cred_name'] = 'registry:slc'
-                    else:
-                        g['cred_name'] = 'registry:comp'
-                p = {}
-                message = {'opname':operation, 'g_params':g, 'p_params':p}
-                #connect to authority
-                server = SSL.Connection(sec.ctx)
-                server.connect(auth_addr)
-                peer = sec.auth_protocol(server)
-                #do the query and get the result
-                server.write(str(message))
-                result = server.read(MAX_CERT_SIZE*MAX_CERT_CHAIN)
-                open(fname, 'w').write(result)
-        return 1
-        
-#obtains a data structure for credentials out of a given credential string
-#return info_cert: {'operation_set':{'register','remove',..}, 'on_interfaces':{{'lbl':'0', 'type':'registry:slc','name':'planetlab.jp'}, ..}}
-def get_cred_info(credstr):
-    info_cert = {'operation_set':{}, 'on_interfaces':{}}
-    set = credstr.split('#')[1].split('credential_set:')[1]
-    set_arr = set.split(')')
-    for item in set_arr[0:len(set_arr)-1]:
-        item = item.split('(')[1].split('-')
-        if info_cert['operation_set'].has_key(item[1]):
-            info_cert['operation_set'][item[1]].append(creds[int(item[0])])
-        else:
-            info_cert['operation_set'][item[1]] = [creds[int(item[0])]]
-    interface_list = []
-    arr = credstr.split('#')
-    intlist = arr[2:len(arr)]
-    for interface in intlist:
-        iarr = interface.split(':')
-        newint = {'lbl':iarr[0]}
-        if iarr[1] == 'reg':
-            if iarr[2] == 'slc':
-                newint['type'] ='registry:slc'
-            else:
-                newint['type'] ='registry:comp'
-            newint['name'] = iarr[3]
-        elif iarr[1] == 'comp':
-            newint['type'] ='component'
-            newint['name'] = iarr[2]
-        interface_list.append(newint)
-    info_cert['on_interfaces'] = interface_list
-    return info_cert
-
-#given two credential statements, check if the first one can delegate the second one
-#example: "'register' right on 'planetlab.jp' registry interface" is able to delegate a right called "'register' right on 'planetlab.jp.jaist' registry interface" 
-def check_delegation(info_cert1, info_cert2):
-    passed = False
-    for interface in info_cert1['on_interfaces']:
-        is_reg = interface['type'] == 'registry:slc' or interface['type'] == 'registry:comp'
-        if is_reg and 'register' in info_cert1['operation_set'][interface['lbl']]:
-            found = True
-            for child_int in info_cert2['on_interfaces']:
-                if child_int['type'] == interface['type'] and not check_authority(child_int['name'],interface['name']):
-                    found = False
-            if found:
-                passed = True
-                break
-    return passed
-
-    """
-Create a credential certificate given the parameters: 
-    'authcert': the authority certificate
-    'authkey': the authority key
-    'pubkey': the public key belonging to the object to which the credential will be granted
-    'cname': the name of the credential being generated. It should be 'registry credentials' or a silce name like 'planetlab.jp.slice1'
-    'rights':  - the sequence representing the set of operations/rights on specific interfaces
-                                            ex: (2-0)(4-0)(6-0)(7-0)(8-0)(9-0)(0-0)(1-1)(2-1)(3-1)(4-1)(5-1)(6-1)(7-1)(8-1)(9-1)#0:reg:planetlab.jp#1:reg:planetlab.jp.jaist
-    'time': time in seconds how long the life of credential is
-"""
-def create_cred(authcert, authkey, pubkey, cname, rights, time=CRED_GRANT_TIME):
-    #calculate the credset
-    if rights == "slice":
-        rights = "(10-1)(11-1)(12-1)(13-1)(14-1)(15-1)(16-1)(17-1)(18-1)(23-1)"
-    elif rights == "SA":
-        rights = "(0-0)(1-0)(2-0)(3-0)(4-0)(5-0)(6-0)(7-0)(8-0)(9-0)(16-1)(17-1)(18-1)(19-1)"
-    elif rights == "MA":
-        rights = "(0-0)(1-0)(2-0)(3-0)(4-0)(5-0)(6-0)(7-0)(8-0)(9-0)(16-1)(17-1)(18-1)"
-    else:
-        # check if the rights is in correct format ######################
-        rights = rights
-        #create the CSR for the credential certificate
-        key = createKeyPair(TYPE_RSA, 1024)
-        certReq = createCertRequest(key, {"CN" : cname})
-        certReq.set_pubkey(pubkey)
-        #create the credential certificate, return
-        content = "#credential_set:"+rights 
-        ext = ("subjectAltName", 1, "URI:http://"+content)
-        exts = [ext]
-        cert = createCertificate(certReq, (authcert, authkey), 0, (0, int(time)), exts)
-        return cert
-
-"""
-Create an accountability certificate given the parameters: 
-    'authc': the name of the authority certificate file
-    'authk': the name of the authority key file
-    'pubkey': the name of the GID file belonging to the object to which the accountability will be assigned
-    'name': the name of the object, which is the accountability information itself
-    'uuid': the uuid of the object
-    'time': the date and time when the life of accounting information
-"""
-def create_acc(authcert, authkey, pubkey, name, uuid, time=ACC_GRANT_TIME): 
-    #create the CSR for the credential certificate
-    key = createKeyPair(TYPE_RSA, 1024)
-    certReq = createCertRequest(key, {"CN" : "GENI Accounting"})
-    certReq.set_pubkey(pubkey)
-    #create the accountability certificate, write into file
-    content = "#hrn:"+name+"#uuid:"+uuid
-    ext = ("subjectAltName", 1, "URI:http://"+content)
-    exts = [ext]
-    cert = createCertificate(certReq, (authcert, authkey), 0, (0, int(time)), exts)
-    return cert
-    
-"""
-Create self signed certificate and private key.
-"""
-def create_self_cert(name):
-    key = createKeyPair(TYPE_RSA, 1024)
-    certReq = createCertRequest(key, {"CN":name})
-    cert = createCertificate(certReq, (certReq, key), 0, (0, 60*60*24*365*5)) # five years
-    open(name+'.pkey', 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))
-    open(name+'.cert', 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
-
-def verify_callback(preverify_ok, ctx):
-    return 1
-    
-class Sec: 
-    def __init__(self, mode, id_file, id_key_file, acc_file, cred_file):
-        self.top_level_certs = []
-        self.mode = mode
-        file_list = os.listdir(TOP_LEVEL_CERTS_DIR)
-        for auth_file in file_list:
-            # XXX SMBAKER: fix .svn directory
-            if os.path.isfile(os.path.join(TOP_LEVEL_CERTS_DIR, auth_file)):
-                self.top_level_certs.append(X509.load_cert(TOP_LEVEL_CERTS_DIR+"/"+auth_file))
-
-        self.id_file = id_file
-        self.id_key_file = id_key_file
-        self.my_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(id_file).read())
-        self.my_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(id_key_file).read())
-        self.acc_file = acc_file
-        self.cred_file = cred_file
-        #ssl parameters
-        self.ctx = SSL.Context()
-        self.ctx.load_cert(self.id_file,self.id_key_file)
-        self.ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9, callback=verify_callback)
-
-    #   - exchange the accounting chains, store peer's accounting in peer.acc
-    #   - check TTLs in certificates
-    #   - check validity of the chain, but do not check top level's trustedness
-    #return 1: means there is a structural error in the chain
-    #return 2: one of the TTLs in the chain not valid
-    #return 3: public keys do not form a valid chain
-    def exchange_accounting(self, conn, peer):
-        peer_acc_str=None
-        if self.mode == 'server':
-            #receive acc chain
-            peer_acc_str = conn.read(MAX_CERT_SIZE*MAX_CERT_CHAIN)
-            #send the acc chain
-            acc_str = open(self.acc_file).read()  #read the certificate chain from file
-            conn.write(acc_str) 
-        elif self.mode == 'client':
-            #send the acc chain
-            acc_str = open(self.acc_file).read()  #read the certificate chain from file
-            conn.write(acc_str)
-            #receive acc chain
-            peer_acc_str = conn.read(MAX_CERT_SIZE*MAX_CERT_CHAIN) 
-            
-        #construct peer_acc data structure
-        peer_acc = peer.acc
-        if peer_acc_str[0:27] != "-----BEGIN CERTIFICATE-----":
-            peer_acc.info_certs = "anonymous"
-        else:
-            try: 
-                #divide the received chain into certificates
-                arr = peer_acc_str.split("-----BEGIN CERTIFICATE-----")
-                arr = arr[1:len(arr)]
-                for i in range(len(arr)):
-                    arr[i] = "-----BEGIN CERTIFICATE-----"+arr[i]
-                for c_str in arr:
-                    c_pem = X509.load_cert_string(c_str)
-                    hrn = c_pem.get_ext("subjectAltName").get_value().split('http://')[1].split('#')[1].split('hrn:')[1]
-                    uuid = c_pem.get_ext("subjectAltName").get_value().split('http://')[1].split('#')[2].split('uuid:')[1]
-                    peer_acc.info_certs.append({'hrn':hrn, 'uuid':uuid})
-                    peer_acc.cert_chain.append(c_pem)
-            except: 
-                print "No valid chain received.\n"
-                return 1
-            #if structure is ok, go on with other checks
-            ttl_ok = True
-            chain_ok = True
-            #check ttl for the first certificate in the chain:
-            if not (check_valid(peer_acc.cert_chain[0])):
-                ttl_ok = False
-            prevCert = None
-            curCert = None
-            for i in range(1, len(peer_acc.cert_chain)):
-                prevCert = peer_acc.cert_chain[i-1] 
-                curCert = peer_acc.cert_chain[i] 
-                #check ttl
-                if not check_valid(curCert):
-                    ttl_ok = False
-                #chain validity checks
-                if not prevCert.verify(curCert.get_pubkey()) :
-                    chain_ok = False
-            if ttl_ok == False:
-                return 2
-            elif chain_ok == False:
-                return 3
-        return 0
-
-    #   - check the pubkey of first certificate if it matches the peer public key
-    #   - check the name hierarchy
-    #   - check the top level authority's trustedness
-    # return 0: accounting verified
-    # return 1: pubkey does not match peer pubkey
-    # return 2: name hierarch does not imply hrn
-    # return 3: top level authority is unknown
-    # return 4: unidentified error
-    def verify_accounting(self, peer):
-        pubkey_ok = True
-        hierarchy_ok = True
-        trusted_auth = True
-        
-        if peer.acc.info_certs == 'anonymous':
-            return 0
-        try:
-            #check the pubkey of the peer
-            if peer.acc.cert_chain[0].get_pubkey().as_pem(cipher=None) != peer.cert.get_pubkey().as_pem(cipher=None):
-                    pubkey_ok = False
-            else:
-                #check the name hierarchy
-                for i in range(len(peer.acc.info_certs)-1):
-                    if check_authority(peer.acc.info_certs[i]['hrn'], peer.acc.info_certs[i+1]['hrn']) == False:
-                        hierarchy_ok = False
-                            
-                #check if the certificate ends with a sign of a trusted top level authority
-                if hierarchy_ok:
-                    found = False
-                    last_cert_pubkey_pem = peer.acc.cert_chain[len(peer.acc.cert_chain)-1].get_pubkey().as_pem(cipher=None)
-                    for cert in self.top_level_certs:
-                        auth_pubkey_pem = cert.get_pubkey().as_pem(cipher=None)
-                        if last_cert_pubkey_pem == auth_pubkey_pem:
-                            found = True 
-                            break
-                    if not found:
-                        trusted_auth = False
-                        
-            if pubkey_ok == False:
-                return 1
-            elif hierarchy_ok == False:
-                return 2
-            elif trusted_auth == False:
-                return 3
-            return 0
-        except Exception, e:
-            print "Exception in verify_accounting:", e
-            return 4
-     
-    #   - exchange the credential chains, store peer's credential in peer.cred
-    #   - check TTLs in certificates
-    #   - check validity of the chain, but do not check top level's trustedness
-    #return 1: means there is a structural error in the chain
-    #return 2: one of the TTLs in the chain not valid
-    #return 3: public keys do not form a valid chain
-    def exchange_credential(self, conn, peer):
-        peer_cred_str = None
-        if self.mode == 'server':
-            #receive cred chain
-            peer_cred_str = conn.read(MAX_CERT_SIZE*MAX_CERT_CHAIN)
-            #send the cred chain
-            cred_str = open(self.cred_file).read()  #read the certificate chain from file
-            conn.write(cred_str)
-        elif self.mode == 'client':
-            #send the cred chain
-            cred_str = open(self.cred_file).read()  #read the certificate chain from file
-            conn.write(cred_str)
-            #receive cred chain
-            peer_cred_str = conn.read(MAX_CERT_SIZE*MAX_CERT_CHAIN)
-            
-        #construct peer_cred data structure
-        peer_cred = peer.cred
-        if peer_cred_str[0:27] != "-----BEGIN CERTIFICATE-----":
-            peer_cred.info_certs = "no_credential"
-        else:
-            try:
-                #divide the received chain into certificates
-                arr = peer_cred_str.split("-----BEGIN CERTIFICATE-----")
-                arr = arr[1:len(arr)]
-                for i in range(len(arr)):
-                    arr[i] = "-----BEGIN CERTIFICATE-----"+arr[i]
-                for c_str in arr:
-                    c_pem = X509.load_cert_string(c_str)
-                    credstr = c_pem.get_ext("subjectAltName").get_value().split('http://')[1]
-                    peer_cred.info_certs.append(get_cred_info(credstr))
-                    peer_cred.cert_chain.append(c_pem)
-            except Exception, e:
-                print "Exception in exchange_credential:", e
-                print "No valid chain received.\n"
-                return 1
-            #if structure is ok, go on with other checks
-            ttl_ok = True
-            chain_ok = True
-            #check ttl for the first certificate in the chain:
-            if not (check_valid(peer_cred.cert_chain[0])):
-                ttl_ok = False
-            prevCert = None
-            curCert = None
-            for i in range(1, len(peer_cred.cert_chain)):
-                prevCert = peer_cred.cert_chain[i-1] 
-                curCert = peer_cred.cert_chain[i] 
-                #check ttl
-                if not check_valid(curCert):
-                    ttl_ok = False
-                #chain validity check
-                if not prevCert.verify(curCert.get_pubkey()) :
-                    chain_ok = False
-            if ttl_ok == False:
-                return 2
-            elif chain_ok == False:
-                return 3
-        return 0
-        
-    #   - check the pubkey of first certificate if it matches the peer public key
-    #   - check the delegation hierarchy: the delegated rights must be granted by an authority of the entity
-    #   - check the top level authority's trustedness
-    # return 0: credential verified
-    # return 1: pubkey does not match peer pubkey
-    # return 2: delegation hierarchy is invalid
-    # return 3: top level authority is unknown
-    # return 4: unidentified error
-    def verify_credential(self, peer):
-        pubkey_ok = True
-        hierarchy_ok = True
-        trusted_auth = True
-        
-        if peer.cred.info_certs == 'no_credential':
-            return 0
-        try:
-            #check the pubkey of the peer
-            if peer.cred.cert_chain[0].get_pubkey().as_pem(cipher=None) != peer.cert.get_pubkey().as_pem(cipher=None):
-                    pubkey_ok = False
-            else:
-                #check the delegation hierarchy
-                for i in range(len(peer.cred.info_certs)-1):
-                    if not check_delegation(peer.cred.info_certs[i+1], peer.cred.info_certs[i]) :
-                        hierarchy_ok = False
-                            
-                #check if the certificate ends with a sign of a trusted top level authority
-                if hierarchy_ok:
-                    found = False
-                    last_cert_pubkey_pem = peer.cred.cert_chain[len(peer.cred.cert_chain)-1].get_pubkey().as_pem(cipher=None)
-                    for cert in self.top_level_certs:
-                        auth_pubkey_pem = cert.get_pubkey().as_pem(cipher=None)
-                        if last_cert_pubkey_pem == auth_pubkey_pem:
-                            found = True 
-                            break
-                    if not found:
-                        trusted_auth = False
-                        
-            if pubkey_ok == False:
-                return 1
-            elif hierarchy_ok == False:
-                return 2
-            elif trusted_auth == False:
-                return 3
-            return 0
-        except:
-            return 4
-
-    def check_authorization(self, acc, cred, op_request):
-        allow = False
-        allow_self = False #admission for ops on only the caller  itself
-        try:
-            opname = op_request['opname']
-            #anonymously callable functions are allowed always
-            if opname == 'getCredential' or opname == 'getAccounting':
-                allow = True
-            else:
-                g_params = op_request['g_params']
-                p_params = op_request['p_params']
-                target_hrn = g_params['hrn']
-                reg_type = ''
-                rec_type = g_params['type']
-                #determine which registry the call is on (slice or component)
-                if rec_type == 'user' or rec_type == 'slice' or rec_type == 'SA':
-                    reg_type = 'slc'
-                else:
-                    reg_type = 'comp'
-                operation_set = cred.get_cred()['operation_set']
-                on_interfaces = cred.get_cred()['on_interfaces'] 
-                is_self_op = False
-                if opname == "update" or opname == "remove" or opname == "lookup":
-                    is_self_op = True
-                #check callable operations within the credential
-                for interface in on_interfaces:
-                    if interface['type'] == 'registry:'+reg_type and check_authority(target_hrn, interface['name']) and operation_set.has_key(interface['lbl']):
-                        if opname in operation_set[interface['lbl']]:
-                            allow = True
-                            break
-                        elif is_self_op and opname + '_self' in operation_set[interface['lbl']] and acc.get_hrn() == target_hrn:
-                            allow_self = True
-                #if operation is allowed in name, perform additional checks for parameters
-                if allow or allow_self:
-                    if opname == 'update':
-                        if  'ttl' in g_params or 'uuid' in g_params or 'pointer' in g_params or (not allow and 'rights' in g_params):
-                            allow = False
-                            allow_self = False
-            #return result
-            if allow or allow_self:
-                return True
-            else:
-                return False
-        except Exception, e:
-            print "exception in check_authorization:", e
-            return False
-
-    def auth_protocol(self, conn):
-        if not conn.verify_ok():
-            v = conn.get_verify_result()
-            print "peer verification failed\n"
-            
-        peer = PeerInfo()    #keep the peer data who is currently logged in
-        #set the gid field
-        peer_pem = conn.get_peer_cert()
-        peer.cert = peer_pem
-        #set the acc field and check it
-        result1 = result2 = -1
-        result1 = self.exchange_accounting(conn, peer)
-        peer_decision = None
-        if self.mode == 'server':
-            peer_decision = conn.read()
-        if result1 == 1:
-            conn.write("ACC CHAIN_STRUCTURE_ERROR")
-        elif result1 == 2:
-            conn.write("ACC TTL_EXPIRED")
-        elif result1 == 3:
-            conn.write("ACC CHAIN_VERIFY_ERROR")
-        else:   #result = 0
-            result2 = self.verify_accounting(peer)
-            if result2 == 1:
-                conn.write("ACC SSL_PUBKEY_MISMATCH")
-            elif result2 == 2:
-                conn.write("ACC HRN_HIERARCHY_MISMATCH")
-            elif result2 == 3:
-                conn.write("ACC UNKNOWN_AUTHORITY")
-            elif result2 == 4:
-                conn.write("ACC UN-IDENTIFIED_ERROR")
-            else:
-                conn.write("ACC OK")
-        if self.mode == 'client':
-            peer_decision = conn.read()
-        if (result1 != 0)  or (result2 != 0) or peer_decision != "ACC OK" : 
-            #close the connection and exit
-            conn.close()
-            return None
-        
-        #set the credential field and check it
-        result1 = result2 = -1
-        result1 = self.exchange_credential(conn,peer)
-        peer_decision = None
-        if self.mode == 'server':
-            peer_decision = conn.read()
-        if result1 == 1:
-            conn.write("CRED CHAIN_STRUCTURE_ERROR")
-        elif result1 == 2:
-            conn.write("CRED TTL_EXPIRED")
-        elif result1 == 3:
-            conn.write("CRED CHAIN_VERIFY_ERROR")
-        else:   #result1 = 0
-            result2 = self.verify_credential(peer)
-            if result2 == 1:
-                conn.write("CRED SSL_PUBKEY_MISMATCH")
-            elif result2 == 2:
-                conn.write("CRED INVALID_DELEGATION")
-            elif result2 == 3:
-                conn.write("CRED UNKNOWN_AUTHORITY")
-            elif result2 == 4:
-                conn.write("CRED UN-IDENTIFIED_ERROR")
-            else:
-                conn.write("CRED OK")
-        if self.mode == 'client':
-            peer_decision = conn.read()
-        if (result1 != 0)  or (result2 != 0) or peer_decision != "CRED OK" : 
-            #close the connection and exit
-            conn.close()
-            return None
-        return peer
-        
-def is_valid_chain(chain_file):
-    chain_str = open(chain_file).read()    
-    if chain_str[0:27] != "-----BEGIN CERTIFICATE-----":
-        return False
-    try:
-        #divide the received chain into certificates
-        arr = chain_str.split("-----BEGIN CERTIFICATE-----")
-        arr = arr[1:len(arr)]
-        for i in range(len(arr)):
-            arr[i] = "-----BEGIN CERTIFICATE-----"+arr[i]
-        arr2 = []
-        for c_str in arr:
-            c_pem = X509.load_cert_string(c_str)
-            if not check_valid(c_pem):
-                return False
-        return True
-    except:
-        return False
-
diff --git a/util/sec/sec.pyc b/util/sec/sec.pyc
deleted file mode 100644 (file)
index fd2b7be..0000000
Binary files a/util/sec/sec.pyc and /dev/null differ