Esempio n. 1
0
    class NodeControl(object):

        def __init__(self, control_uri, barrier):
            super(NodeControl, self).__init__()
            self._id = None
            self._uri = None
            self.control_uri = control_uri
            self.request_handler = RequestHandler()
            # When barrier ordered make sure we can contact the runtime
            if barrier:
                failed = True
                # Try 20 times waiting for control API to be up and running
                for i in range(20):
                    try:
                        self._id = self.request_handler.get_node_id(self)
                        failed = False
                        break
                    except:
                        time.sleep(0.1)
                assert not failed

        @property
        def id(self):
            if self._id is None:
                self._id = self.request_handler.get_node_id(self)
            return self._id

        @property
        def uri(self):
            if self._uri is None:
                self._uri = self.request_handler.get_node(self, self.id)["uri"]
            return self._uri
Esempio n. 2
0
    class NodeControl(object):
        def __init__(self, control_uri, barrier):
            super(NodeControl, self).__init__()
            self._id = None
            self._uris = None
            self.control_uri = control_uri
            self.request_handler = RequestHandler()
            delay = 0.1
            # When barrier ordered make sure we can contact the runtime
            if barrier:
                success = False
                # Try 20 times waiting for control API to be up and running
                for i in range(20):
                    try:
                        self._id = self.request_handler.get_node_id(self)
                        success = True
                        break
                    except Exception:
                        time.sleep(delay)
                        delay = 2 * delay if delay < 1.0 else 1.0
                assert success

        @property
        def id(self):
            if self._id is None:
                self._id = self.request_handler.get_node_id(self)
            return self._id

        @property
        def uris(self):
            if self._uris is None:
                self._uris = self.request_handler.get_node(self,
                                                           self.id)["uris"]
            return self._uris
Esempio n. 3
0
def setup_module(module):
    global request_handler
    global runtime1

    request_handler = RequestHandler()
    runtime1 = RT("http://127.0.0.1:5001")
    runtime1.id = request_handler.get_node_id(runtime1.control_uri)
class CalvinActorMigrationTestBase(unittest.TestCase):
    """ Base class for test actor migration. Based on CalvinTestBase but without the global variables """
    def setUp(self):
        self.request_handler = RequestHandler()
        self.test_type, [self.rt1, self.rt2, self.rt3] = helpers.setup_test_type(self.request_handler)

    def tearDown(self):
        helpers.teardown_test_type(self.request_handler, [self.rt1, self.rt2, self.rt3], self.test_type)

    def wait_for_migration(self, runtime, actors, retries=20):
        retry = 0
        if not isinstance(actors, list):
            actors = [actors]
        while retry < retries:
            try:
                current = self.request_handler.get_actors(runtime)
                if set(actors).issubset(set(current)):
                    break
                else:
                    _log.info("Migration not finished, retrying in %f" % (retry * 0.1,))
                    retry += 1
                    time.sleep(retry * 0.1)
            except Exception as e:
                _log.info("Migration not finished %s, retrying in %f" % (str(e), retry * 0.1,))
                retry += 1
                time.sleep(retry * 0.1)
        if retry == retries:
            _log.info("Migration failed, after %d retries" % (retry,))
            raise Exception("Migration failed")

    def migrate(self, source, dest, actor):
        self.request_handler.migrate(source, actor, dest.id)
        self.wait_for_migration(dest, [actor])
Esempio n. 5
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        global runtimes
        global rt_attributes
        global request_handler
        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old testdir, err={}".format(err)
            pass
        try:
            shutil.copytree(orig_identity_provider_path, identity_provider_path)
        except Exception as err:
            _log.error("Failed to create test folder structure, err={}".format(err))
            print "Failed to create test folder structure, err={}".format(err)
            raise
        helpers.sign_files_for_security_tests(credentials_testdir)
        runtimes = helpers.create_CA_and_generate_runtime_certs(domain_name, credentials_testdir, NBR_OF_RUNTIMES)

        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(type=certificate.TRUSTSTORE_TRANSPORT, 
                                                         security_dir=credentials_testdir)
        request_handler = RequestHandler(verify=truststore_dir)
        #Let's use the admin user0 for request_handler 
        request_handler.set_credentials({"user": "******", "password": "******"})

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt_conf.set('global', 'actor_paths', [actor_store_path])

        # Runtime 0: Certificate authority, authentication server, authorization server, proxy storage server.
        rt0_conf = copy.deepcopy(rt_conf)
        rt0_conf.set('global','storage_type','local')
        rt0_conf.set("security", "security_conf", {
                        "comment": "Authentication server accepting external requests",
                        "authentication": {
                            "procedure": "local",
                            "identity_provider_path": identity_provider_path,
                            "accept_external_requests": True
                        }
                    })
        rt0_conf.save("/tmp/calvin5000.conf")

        # Other runtimes 
        rt_conf.set('global','storage_type','proxy')
        rt_conf.set('global','storage_proxy',"calvinip://%s:5000" % ip_addr )
        rt_conf.set("security", "security_conf", {
                        "comment": "External authentication",
                        "authentication": {
                            "procedure": "external"
                        }
                    })

        for i in range(1, NBR_OF_RUNTIMES):
            rt_conf.save("/tmp/calvin500{}.conf".format(i))

        helpers.start_all_runtimes(runtimes, hostname, request_handler)
        request.addfinalizer(self.teardown)
Esempio n. 6
0
 def setUp(self):
     global request_handler
     request_handler = RequestHandler()
     self.rt1, _ = dispatch_node(["calvinip://%s:5000" % (ip_addr,)], "http://%s:5003" % ip_addr)
     self.rt2, _ = dispatch_node(["calvinip://%s:5001" % (ip_addr,)], "http://%s:5004" % ip_addr)
     self.rt3, _ = dispatch_node(["calvinip://%s:5002" % (ip_addr,)], "http://%s:5005" % ip_addr)
     request_handler.peer_setup(self.rt1, ["calvinip://%s:5001" % (ip_addr,), "calvinip://%s:5002" % (ip_addr, )])
     request_handler.peer_setup(self.rt2, ["calvinip://%s:5000" % (ip_addr,), "calvinip://%s:5002" % (ip_addr, )])
     request_handler.peer_setup(self.rt3, ["calvinip://%s:5000" % (ip_addr,), "calvinip://%s:5001" % (ip_addr, )])
Esempio n. 7
0
def get_node_id(rt):
    request_handler = RequestHandler()
    for x in range(0, 10):
        try:
            rt.id = request_handler.get_node_id(rt.control_uri)
            return True
        except:
            pass
        time.sleep(1)
    print "Failed to get node id from '%s'" % rt.control_uri
    return False
Esempio n. 8
0
 def __init__(self, runtime, deployable, credentials=None, verify=True):
     super(Deployer, self).__init__()
     self.runtime = runtime
     self.deployable = deployable
     self.credentials = credentials
     self.actor_map = {}
     self.app_id = None
     self.verify = verify
     self.request_handler = RequestHandler()
     if "name" in self.deployable:
         self.name = self.deployable["name"]
     else:
         self.name = None
Esempio n. 9
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global runtimes
        global rt_attributes
        global request_handler
        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        helpers.sign_files_for_security_tests(credentials_testdir)
        runtimes = helpers.create_CA_and_generate_runtime_certs(domain_name, credentials_testdir, NBR_OF_RUNTIMES)

        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(type=certificate.TRUSTSTORE_TRANSPORT, 
                                                         security_dir=credentials_testdir)
        request_handler = RequestHandler(verify=truststore_dir)

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'domain_name', domain_name)
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt_conf.set('global', 'actor_paths', [actor_store_path])
        rt_conf.set('global', 'storage_type', "securedht")

        for i in range(NBR_OF_RUNTIMES):
            rt_conf.set('security','certificate_authority',{
                'domain_name':domain_name
            })
            rt_conf.save("/tmp/calvin{}.conf".format(5000+i))

        helpers.start_all_runtimes(runtimes, hostname, request_handler)
        request.addfinalizer(self.teardown)
Esempio n. 10
0
class Deployer(object):
    """
    Deprecated!
    Thin layer to support legacy users.
    New users should use the control REST API or the RequestHandler.deploy_application or RequestHandler.deploy_app_info
    Deploys an application to a runtime.
    """
    def __init__(self, runtime, deployable, credentials=None, verify=True):
        super(Deployer, self).__init__()
        self.runtime = runtime
        self.deployable = deployable
        self.credentials = credentials
        self.actor_map = {}
        self.app_id = None
        self.verify = verify
        self.request_handler = RequestHandler()
        if "name" in self.deployable:
            self.name = self.deployable["name"]
        else:
            self.name = None

    def deploy(self):
        """
        Ask a runtime to instantiate actors and link them together.
        """
        if not self.deployable['valid']:
            import json
            print(json.dumps(self.deployable, indent=2, default=str))
            raise Exception("Deploy information is not valid")

        result = self.request_handler.deploy_app_info(
            self.runtime,
            self.name,
            self.deployable,
            credentials=self.credentials,
            check=self.verify)
        self.app_id = result['application_id']
        self.actor_map = result['actor_map']

        return self.app_id

    def destroy(self):
        return self.request_handler.delete_application(self.runtime,
                                                       self.app_id)
Esempio n. 11
0
 def __init__(self, node):
     _log.debug("Security: _init_")
     self.sec_conf = _conf.get("security","security_conf")
     if self.sec_conf is not None and not self.sec_conf.get('signature_trust_store', None):
         # Set default directory for trust store
         homefolder = os.path.expanduser("~")
         truststore_dir = os.path.join(homefolder, ".calvin", "security", "trustStore")
         self.sec_conf['signature_trust_store'] = truststore_dir
     self.node = node
     self.subject = {}
     self.auth = {}
     self.request_handler = RequestHandler()
Esempio n. 12
0
def setup_module(module):
    global request_handler
    global runtime1
    global runtime2
    global constrained_id
    global constrained_process

    request_handler = RequestHandler()
    runtime1 = RT("http://127.0.0.1:5001")
    runtime1.id = request_handler.get_node_id(runtime1.control_uri)
    runtime2 = RT("http://127.0.0.1:5003")
    runtime2.id = request_handler.get_node_id(runtime2.control_uri)

    # start constrained
    constrained_process = subprocess.Popen(
        calvin_command +
        " -a '{\"indexed_public\": {\"node_name\": {\"organization\": \"com.ericsson\", \"purpose\": \"distributed-test\", \"group\": \"rest\", \"name\": \"constrained\"}}}' -u '[\"calvinip://127.0.0.1:5000\", \"ssdp\"]'",
        shell=True)
    for x in range(0, 10):
        peers = request_handler.get_nodes(runtime1)
        for peer in peers:
            peer_info = request_handler.get_node(runtime1, peer)
            if "constrained" in peer_info["attributes"]["indexed_public"][0]:
                constrained_id = peer
                return
        time.sleep(1)

    pytest.exit("Failed to get constrained runtimes")
class CalvinActorMigrationTestBase(unittest.TestCase):
    """ Base class for test actor migration. Based on CalvinTestBase but without the global variables """
    def setUp(self):
        self.request_handler = RequestHandler()
        self.test_type, [self.rt1, self.rt2, self.rt3
                         ] = helpers.setup_test_type(self.request_handler)

    def tearDown(self):
        helpers.teardown_test_type(self.request_handler,
                                   [self.rt1, self.rt2, self.rt3],
                                   self.test_type)

    def wait_for_migration(self, runtime, actors, retries=20):
        retry = 0
        if not isinstance(actors, list):
            actors = [actors]
        while retry < retries:
            try:
                current = self.request_handler.get_actors(runtime)
                if set(actors).issubset(set(current)):
                    break
                else:
                    _log.info("Migration not finished, retrying in %f" %
                              (retry * 0.1, ))
                    retry += 1
                    time.sleep(retry * 0.1)
            except Exception as e:
                _log.info("Migration not finished %s, retrying in %f" % (
                    str(e),
                    retry * 0.1,
                ))
                retry += 1
                time.sleep(retry * 0.1)
        if retry == retries:
            _log.info("Migration failed, after %d retries" % (retry, ))
            raise Exception("Migration failed")

    def migrate(self, source, dest, actor):
        self.request_handler.migrate(source, actor, dest.id)
        self.wait_for_migration(dest, [actor])
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global rt
        global rt_attributes
        global request_handler
        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        #This test does not really need signed actors/applications, but do it anyway to be
        #be able to deploy application similarly as the other security tests
        helpers.sign_files_for_security_tests(credentials_testdir)
        runtimes = helpers.create_CA_and_get_enrollment_passwords(
            domain_name, credentials_testdir, NBR_OF_RUNTIMES)

        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(
            type=certificate.TRUSTSTORE_TRANSPORT,
            security_dir=credentials_testdir)
        request_handler = RequestHandler(verify=truststore_dir)

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt_conf.set('global', 'actor_paths', [actor_store_path])
        rt_conf.set('security', 'control_interface_security', "tls")
        rt_conf.set('global', 'storage_type', "securedht")

        # Runtime 0: Certificate authority.
        rt0_conf = copy.deepcopy(rt_conf)
        rt0_conf.set('security', 'certificate_authority', {
            'domain_name': domain_name,
            'is_ca': 'True'
        })
        rt0_conf.save("/tmp/calvin5000.conf")

        for i in range(1, NBR_OF_RUNTIMES):
            rt_conf.set(
                'security', 'certificate_authority', {
                    'domain_name': domain_name,
                    'is_ca': 'False',
                    'enrollment_password': runtimes[i]["enrollment_password"]
                })
            rt_conf.save("/tmp/calvin{}.conf".format(5000 + i))

        rt = helpers.start_all_runtimes(runtimes,
                                        hostname,
                                        request_handler,
                                        tls=True)
        request.addfinalizer(self.teardown)
Esempio n. 15
0
 def __init__(self, runtime, deployable, credentials=None, verify=True):
     super(Deployer, self).__init__()
     self.runtime = runtime
     self.deployable = deployable
     self.credentials = credentials
     self.actor_map = {}
     self.app_id = None
     self.verify = verify
     self.request_handler = RequestHandler()
     if "name" in self.deployable:
         self.name = self.deployable["name"]
     else:
         self.name = None
Esempio n. 16
0
class Deployer(object):

    """
    Deprecated!
    Thin layer to support legacy users.
    New users should use the control REST API or the RequestHandler.deploy_application or RequestHandler.deploy_app_info
    Deploys an application to a runtime.
    """

    def __init__(self, runtime, deployable, credentials=None, verify=True):
        super(Deployer, self).__init__()
        self.runtime = runtime
        self.deployable = deployable
        self.credentials = credentials
        self.actor_map = {}
        self.app_id = None
        self.verify = verify
        self.request_handler = RequestHandler()
        if "name" in self.deployable:
            self.name = self.deployable["name"]
        else:
            self.name = None

    def deploy(self):
        """
        Ask a runtime to instantiate actors and link them together.
        """
        if not self.deployable['valid']:
            raise Exception("Deploy information is not valid")

        result = self.request_handler.deploy_app_info(self.runtime, self.name, self.deployable,
                                       credentials=self.credentials, check=self.verify)
        self.app_id = result['application_id']
        self.actor_map = result['actor_map']

        return self.app_id

    def destroy(self):
        return self.request_handler.delete_application(self.runtime, self.app_id)
Esempio n. 17
0
def dispatch_and_deploy(app_info, wait, uris, control_uri, attr, credentials):
    from calvin.requests.request_handler import RequestHandler
    rt, process = runtime(uris, control_uri, attr, dispatch=True)
    app_id = None
    app_id = deploy(rt, app_info, credentials)
    print "Deployed application", app_id

    timeout = wait if wait else None
    if timeout:
        process.join(timeout)
        RequestHandler().quit(rt)
        time.sleep(0.1)
    else:
        process.join()
Esempio n. 18
0
 def setUp(self):
     global request_handler
     request_handler = RequestHandler()
     self.rt1, _ = dispatch_node(["calvinip://%s:5000" % (ip_addr,)], "http://%s:5003" % ip_addr)
     self.rt2, _ = dispatch_node(["calvinip://%s:5001" % (ip_addr,)], "http://%s:5004" % ip_addr)
     self.rt3, _ = dispatch_node(["calvinip://%s:5002" % (ip_addr,)], "http://%s:5005" % ip_addr)
     request_handler.peer_setup(self.rt1, ["calvinip://%s:5001" % (ip_addr,), "calvinip://%s:5002" % (ip_addr, )])
     request_handler.peer_setup(self.rt2, ["calvinip://%s:5000" % (ip_addr,), "calvinip://%s:5002" % (ip_addr, )])
     request_handler.peer_setup(self.rt3, ["calvinip://%s:5000" % (ip_addr,), "calvinip://%s:5001" % (ip_addr, )])
Esempio n. 19
0
def dispatch_and_deploy(app_info, wait, uris, control_uri, attr, credentials):
    from calvin.requests.request_handler import RequestHandler
    rt, process = runtime(uris, control_uri, attr, dispatch=True)
    app_id = None
    app_id = deploy(rt, app_info, credentials)
    print "Deployed application", app_id

    timeout = wait if wait else None
    if timeout:
        process.join(timeout)
        RequestHandler().quit(rt)
        # This time has to be long enough for the mainloop to wrap things up, otherwise the program will hang indefinitely
        time.sleep(1.0)
    else:
        process.join()
Esempio n. 20
0
    def setUp(self):
        global request_handler
        request_handler = RequestHandler()
        self.rt1, _ = dispatch_node(["calvinip://%s:5000" % (ip_addr,)], "http://%s:5003" % ip_addr,
             attributes={'indexed_public':
                  {'owner':{'organization': 'org.testexample', 'personOrGroup': 'testOwner1'},
                   'node_name': {'organization': 'org.testexample', 'name': 'testNode1'},
                   'address': {'country': 'SE', 'locality': 'testCity', 'street': 'testStreet', 'streetNumber': 1}}})

        self.rt2, _ = dispatch_node(["calvinip://%s:5001" % (ip_addr,)], "http://%s:5004" % ip_addr,
             attributes={'indexed_public':
                  {'owner':{'organization': 'org.testexample', 'personOrGroup': 'testOwner1'},
                   'node_name': {'organization': 'org.testexample', 'name': 'testNode2'},
                   'address': {'country': 'SE', 'locality': 'testCity', 'street': 'testStreet', 'streetNumber': 1}}})
        self.rt3, _ = dispatch_node(["calvinip://%s:5002" % (ip_addr,)], "http://%s:5005" % ip_addr,
             attributes={'indexed_public':
                  {'owner':{'organization': 'org.testexample', 'personOrGroup': 'testOwner2'},
                   'node_name': {'organization': 'org.testexample', 'name': 'testNode3'},
                   'address': {'country': 'SE', 'locality': 'testCity', 'street': 'testStreet', 'streetNumber': 2}}})
Esempio n. 21
0
def setup_module(module):
    global runtime
    global runtimes
    global peerlist
    global kill_peers
    global request_handler
    ip_addr = None
    bt_master_controluri = None

    request_handler = RequestHandler()
    try:
        ip_addr = os.environ["CALVIN_TEST_IP"]
        purpose = os.environ["CALVIN_TEST_UUID"]
    except KeyError:
        pass

    if ip_addr is None:
        # Bluetooth tests assumes one master runtime with two connected peers
        # CALVIN_TEST_BT_MASTERCONTROLURI is the control uri of the master runtime
        try:
            bt_master_controluri = os.environ[
                "CALVIN_TEST_BT_MASTERCONTROLURI"]
            _log.debug("Running Bluetooth tests")
        except KeyError:
            pass

    if ip_addr:
        remote_node_count = 2
        kill_peers = False
        test_peers = None

        import socket
        ports = []
        for a in range(2):
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.bind(('', 0))
            addr = s.getsockname()
            ports.append(addr[1])
            s.close()

        runtime, _ = dispatch_node(["calvinip://%s:%s" % (ip_addr, ports[0])],
                                   "http://%s:%s" % (ip_addr, ports[1]))

        _log.debug(
            "First runtime started, control http://%s:%s, calvinip://%s:%s" %
            (ip_addr, ports[1], ip_addr, ports[0]))

        interval = 0.5
        for retries in range(1, 20):
            time.sleep(interval)
            _log.debug("Trying to get test nodes for 'purpose' %s" % purpose)
            test_peers = request_handler.get_index(
                runtime,
                format_index_string({
                    'node_name': {
                        'organization': 'com.ericsson',
                        'purpose': purpose
                    }
                }))
            if not test_peers is None and not test_peers["result"] is None and \
                    len(test_peers["result"]) == remote_node_count:
                test_peers = test_peers["result"]
                break

        if test_peers is None or len(test_peers) != remote_node_count:
            _log.debug(
                "Failed to find all remote nodes within time, peers = %s" %
                test_peers)
            raise Exception("Not all nodes found dont run tests, peers = %s" %
                            test_peers)

        test_peer2_id = test_peers[0]
        test_peer2 = request_handler.get_node(runtime, test_peer2_id)
        if test_peer2:
            runtime2 = RT(test_peer2["control_uri"])
            runtime2.id = test_peer2_id
            runtime2.uri = test_peer2["uri"]
            runtimes.append(runtime2)
        test_peer3_id = test_peers[1]
        if test_peer3_id:
            test_peer3 = request_handler.get_node(runtime, test_peer3_id)
            if test_peer3:
                runtime3 = RT(test_peer3["control_uri"])
                runtime3.id = test_peer3_id
                runtime3.uri = test_peer3["uri"]
                runtimes.append(runtime3)
    elif bt_master_controluri:
        runtime = RT(bt_master_controluri)
        bt_master_id = request_handler.get_node_id(bt_master_controluri)
        data = request_handler.get_node(runtime, bt_master_id)
        if data:
            runtime.id = bt_master_id
            runtime.uri = data["uri"]
            test_peers = request_handler.get_nodes(runtime)
            test_peer2_id = test_peers[0]
            test_peer2 = request_handler.get_node(runtime, test_peer2_id)
            if test_peer2:
                rt2 = RT(test_peer2["control_uri"])
                rt2.id = test_peer2_id
                rt2.uri = test_peer2["uri"]
                runtimes.append(rt2)
            test_peer3_id = test_peers[1]
            if test_peer3_id:
                test_peer3 = request_handler.get_node(runtime, test_peer3_id)
                if test_peer3:
                    rt3 = request_handler.RT(test_peer3["control_uri"])
                    rt3.id = test_peer3_id
                    rt3.uri = test_peer3["uri"]
                    runtimes.append(rt3)
    else:
        try:
            ip_addr = os.environ["CALVIN_TEST_LOCALHOST"]
        except:
            import socket
            ip_addr = socket.gethostbyname(socket.gethostname())
        localhost = "calvinip://%s:5000" % (ip_addr, ), "http://localhost:5001"
        remotehosts = [("calvinip://%s:%d" % (ip_addr, d),
                        "http://localhost:%d" % (d + 1))
                       for d in range(5002, 5005, 2)]
        # remotehosts = [("calvinip://127.0.0.1:5002", "http://localhost:5003")]

        for host in remotehosts:
            runtimes += [dispatch_node([host[0]], host[1])[0]]

        runtime, _ = dispatch_node([localhost[0]], localhost[1])

        time.sleep(1)

        # FIXME When storage up and running peersetup not needed, but still useful during testing
        request_handler.peer_setup(runtime, [i[0] for i in remotehosts])

        time.sleep(0.5)
        """

        # FIXME Does not yet support peerlist
        try:
            self.peerlist = peerlist(
                self.runtime, self.runtime.id, len(remotehosts))

            # Make sure all peers agree on network
            [peerlist(self.runtime, p, len(self.runtimes)) for p in self.peerlist]
        except:
            self.peerlist = []
        """

    peerlist = [rt.control_uri for rt in runtimes]
    print "SETUP DONE ***", peerlist
Esempio n. 22
0
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from calvin.utilities.nodecontrol import dispatch_node
from calvin.requests.request_handler import RequestHandler
import time

# Get the handler for sending the API requests
request_handler = RequestHandler()

# create one node
node_1 = dispatch_node(uri="calvinip://localhost:5000", control_uri="http://localhost:5001",
                       attributes={'indexed_public':
                            {'owner':{'organization': 'org.testexample', 'personOrGroup': 'me'},
                             'node_name': {'organization': 'org.testexample', 'name': 'node-1'}}})

# send 'new actor' command to node
counter_id = request_handler.new_actor(node_1, 'std.Counter', 'counter')

# send 'new actor' command to node
output_id = request_handler.new_actor(node_1, 'io.StandardOut', 'output')

# send 'connect' command to node
request_handler.connect(node_1, output_id, 'token', node_1.id, counter_id, 'integer')
Esempio n. 23
0
def runtime_certificate(rt_attributes):
    import copy
    import requests
    import sys
    from calvin.requests.request_handler import RequestHandler
    from calvin.utilities.attribute_resolver import AttributeResolver
    from calvin.utilities import calvinconfig
    from calvin.utilities import calvinuuid
    from calvin.utilities import runtime_credentials
    from calvin.utilities import certificate
    from calvin.utilities import certificate_authority
    from calvin.runtime.south.plugins.storage.twistedimpl.dht.service_discovery_ssdp import parse_http_response
    global _conf
    global _log
    _conf = calvinconfig.get()
    if not _conf.get_section("security"):
        #If the security section is empty, no securty features are enabled and certificates aren't needed
        _log.debug("No runtime security enabled")
    else:
        _log.debug(
            "Some security features are enabled, let's make sure certificates are in place"
        )
        _ca_conf = _conf.get("security", "certificate_authority")
        security_dir = _conf.get("security", "security_dir")
        storage_type = _conf.get("global", "storage_type")
        if _ca_conf:
            try:
                ca_ctrl_uri = _ca_conf[
                    "ca_control_uri"] if "ca_control_uri" in _ca_conf else None
                domain_name = _ca_conf[
                    "domain_name"] if "domain_name" in _ca_conf else None
                is_ca = _ca_conf["is_ca"] if "is_ca" in _ca_conf else None
                enrollment_password = _ca_conf[
                    "enrollment_password"] if "enrollment_password" in _ca_conf else None
            except Exception as err:
                _log.error(
                    "runtime_certificate: Failed to parse security configuration in calvin.conf, err={}"
                    .format(err))
                raise
            #AttributeResolver tranforms the attributes, so make a deepcopy instead
            rt_attributes_cpy = copy.deepcopy(rt_attributes)
            attributes = AttributeResolver(rt_attributes_cpy)
            node_name = attributes.get_node_name_as_str()
            nodeid = calvinuuid.uuid("")
            runtime = runtime_credentials.RuntimeCredentials(
                node_name,
                domain_name,
                security_dir=security_dir,
                nodeid=nodeid,
                enrollment_password=enrollment_password)
            certpath, cert, certstr = runtime.get_own_cert()
            if not cert:
                csr_path = os.path.join(runtime.runtime_dir,
                                        node_name + ".csr")
                if is_ca == "True":
                    _log.debug(
                        "No runtime certificate, but node is a CA, just sign csr, domain={}"
                        .format(domain_name))
                    ca = certificate_authority.CA(domain=domain_name,
                                                  security_dir=security_dir)
                    cert_path = ca.sign_csr(csr_path, is_ca=True)
                    runtime.store_own_cert(certpath=cert_path,
                                           security_dir=security_dir)

                else:
                    _log.debug(
                        "No runtime certicificate can be found, send CSR to CA"
                    )
                    truststore_dir = certificate.get_truststore_path(
                        type=certificate.TRUSTSTORE_TRANSPORT,
                        security_dir=security_dir)
                    request_handler = RequestHandler(verify=truststore_dir)
                    ca_control_uris = []
                    #TODO: add support for multiple CA control uris
                    if ca_ctrl_uri:
                        _log.debug(
                            "CA control_uri in config={}".format(ca_ctrl_uri))
                        ca_control_uris.append(ca_ctrl_uri)
                    elif storage_type in ["dht", "securedht"]:
                        _log.debug("Find CA via SSDP")
                        responses = discover()
                        if not responses:
                            _log.error("No responses received")
                        for response in responses:
                            cmd, headers = parse_http_response(response)
                            if 'location' in headers:
                                ca_control_uri, ca_node_id = headers[
                                    'location'].split('/node/')
                                ca_control_uri = ca_control_uri.replace(
                                    "http", "https")
                                ca_control_uris.append(ca_control_uri)
                                _log.debug(
                                    "CA control_uri={}, node_id={}".format(
                                        ca_control_uri, ca_node_id))
                    else:
                        _log.error(
                            "There is no runtime certificate. For automatic certificate enrollment using proxy storage,"
                            "the CA control uri must be configured in the calvin configuration "
                        )
                        raise Exception(
                            "There is no runtime certificate. For automatic certificate enrollment using proxy storage,"
                            "the CA control uri must be configured in the calvin configuration "
                        )
                    cert_available = False
                    # Loop through all CA:s that responded until hopefully one signs our CSR
                    # Potential improvement would be to have domain name in response and only try
                    # appropriate CAs
                    i = 0
                    while not cert_available and i < len(ca_control_uris):
                        certstr = None
                        #Repeatedly (maximum 10 attempts) send CSR to CA until a certificate is returned (this to remove the requirement of the CA
                        #node to be be the first node to start)
                        rsa_encrypted_csr = runtime.get_encrypted_csr()
                        j = 0
                        while not certstr and j < 10:
                            try:
                                certstr = request_handler.sign_csr_request(
                                    ca_control_uris[i],
                                    rsa_encrypted_csr)['certificate']
                            except requests.exceptions.RequestException as err:
                                time_to_sleep = 1 + j * j * j
                                _log.debug(
                                    "RequestException, CSR not accepted or CA not up and running yet, sleep {} seconds and try again, err={}"
                                    .format(time_to_sleep, err))
                                time.sleep(time_to_sleep)
                                j = j + 1
                                pass
                            else:
                                cert_available = True
                        i = i + 1
                    #TODO: check that everything is ok with signed cert, e.g., check that the CA domain
                    # matches the expected and that the CA cert is trusted
                    runtime.store_own_cert(certstring=certstr,
                                           security_dir=security_dir)
            else:
                _log.debug("Runtime certificate available")
Esempio n. 24
0
 def setUp(self):
     global request_handler
     request_handler = RequestHandler()
     self.hosts = []
     self.rt = []
Esempio n. 25
0
def get_request_handler():
    from calvin.requests.request_handler import RequestHandler
    return _request_handler if _request_handler else RequestHandler()
Esempio n. 26
0
class Security(object):

    def __init__(self, node):
        _log.debug("Security: _init_")
        self.sec_conf = _conf.get("security","security_conf")
        if self.sec_conf is not None and not self.sec_conf.get('signature_trust_store', None):
            # Set default directory for trust store
            homefolder = os.path.expanduser("~")
            truststore_dir = os.path.join(homefolder, ".calvin", "security", "trustStore")
            self.sec_conf['signature_trust_store'] = truststore_dir
        self.node = node
        self.subject = {}
        self.auth = {}
        self.request_handler = RequestHandler()

    def __str__(self):
        return "Subject: %s\nAuth: %s" % (self.subject, self.auth)

    def set_subject(self, subject):
        """Set subject attributes and mark them as unauthenticated"""
        _log.debug("Security: set_subject %s" % subject)
        if not isinstance(subject, dict):
            return False
        # Make sure that all subject values are lists.
        self.subject = {k: list(v) if isinstance(v, (list, tuple, set)) else [v]
                            for k, v in subject.iteritems()}
        # Set the corresponding values of self.auth to False to indicate that they are unauthenticated.
        self.auth = {k: [False]*len(v) for k, v in self.subject.iteritems()}

    def authenticate_subject(self):
        """Authenticate subject using the authentication procedure specified in config."""
        _log.debug("Security: authenticate_subject")
        if not security_needed_check():
            _log.debug("Security: authenticate_subject no security needed")
            return True

        if self.sec_conf['authentication']['procedure'] == "local":
            _log.debug("Security: local authentication method chosen")
            return self.authenticate_using_local_database()
        if self.sec_conf['authentication']['procedure'] == "radius":
            if not HAS_PYRAD:
                _log.error("Security: Install pyrad to use radius server as authentication method.\n" +
                            "Note! NO AUTHENTICATION USED")
                return False
            _log.debug("Security: Radius authentication method chosen")
            return self.authenticate_using_radius_server()
        _log.debug("Security: No security config, so authentication disabled")
        return True

    def authenticate_using_radius_server(self):
        """
        Authenticate a subject using a RADIUS server.

        The corresponding value in self.auth is set to True
        if authentication is successful.
        """
        auth = []
        if self.subject['user']:
            root_dir = os.path.abspath(os.path.join(_conf.install_location(), '..'))
            srv=Client(server=self.sec_conf['authentication']['server_ip'], 
                        secret= bytes(self.sec_conf['authentication']['secret']),
                        dict=Dictionary(os.path.join(root_dir, "pyrad_dicts", "dictionary"), 
                                        os.path.join(root_dir, "pyrad_dicts", "dictionary.acc")))
            req=srv.CreateAuthPacket(code=pyrad.packet.AccessRequest,
                        User_Name=self.subject['user'][0],
                        NAS_Identifier="localhost")
            req["User-Password"]=req.PwCrypt(self.subject['password'][0])
            # FIXME is this over socket? then we should not block here
            reply=srv.SendPacket(req)
            _log.debug("Attributes returned by server:")
            for i in reply.keys():
                _log.debug("%s: %s" % (i, reply[i]))
            if reply.code==pyrad.packet.AccessAccept:
                _log.debug("Security: access accepted")
                auth.append(True)
#                return True
            else:
                _log.debug("Security: access denied")
                auth.append(False)
#                return False
        self.auth['user']=auth
        return any(auth)

    def authenticate_using_local_database(self):
        """
        Authenticate a subject against information stored in config.

        The corresponding value in self.auth is set to True
        if authentication is successful.

        This is primarily intended for testing purposes,
        since passwords aren't stored securely.
        """
        if 'local_users' not in self.sec_conf['authentication']:
            _log.debug("local_users not found in security_conf: %s" % self.sec_conf['authentication'])
            return False
        # Verify users against stored passwords
        # TODO expand with other subject types
        d = self.sec_conf['authentication']['local_users']
        if not ('user' in self.subject and 'password' in self.subject):
            return False
        if len(self.subject['user']) != len(self.subject['password']):
            return False
        auth = []
        for user, password in zip(self.subject['user'], self.subject['password']):
            if user in d.keys():
                if d[user] == password:
                    _log.debug("Security: found user: %s",user)
                    auth.append(True)
                else:
                    _log.debug("Security: incorrect username or password")
                    auth.append(False)
            else:
                auth.append(False)
        self.auth['user'] = auth
        return any(auth)

    def get_authenticated_subject_attributes(self):
        """Return a dictionary with all authenticated subject attributes."""
        return {key: [self.subject[key][i] for i, auth in enumerate(values) if auth] 
                for key, values in self.auth.iteritems() if any(values)}

    def check_security_policy(self, requires=None):
        """Check if access is permitted for the actor by the security policy"""
        _log.debug("Security: check_security_policy")
        if self.sec_conf and "authorization" in self.sec_conf:
            return self.get_authorization_decision(requires)
        # No security config, so access control is disabled
        return True

    def get_authorization_decision(self, requires=None):
        """Get authorization decision using the authorization procedure specified in config."""
        #Delete
        return True
        request = {}
        request["subject"] = self.get_authenticated_subject_attributes()
        request["resource"] = {"node_id": self.node.id}
        if requires is not None:
            request["action"] = {"requires": requires}
        _log.debug("Security: authorization request: %s" % request)

        # Check if the authorization server is local (the runtime itself) or external.
        if self.sec_conf['authorization']['procedure'] == "external":
            if not HAS_JWT:
                _log.error("Security: Install JWT to use external server as authorization method.\n" +
                        "Note: NO AUTHORIZATION USED")
                return False
            _log.debug("Security: external authorization method chosen")
            decision, obligations = self.authorize_using_external_server(request)
        else: 
            _log.debug("Security: local authorization method chosen")
            decision, obligations = self.authorize_using_local_policies(request)

        if decision == "permit":
            _log.debug("Security: access permitted to resources")
            if obligations:
                return (True, obligations)
            return True
        elif decision == "deny":
            _log.debug("Security: access denied to resources")
            return False
        elif decision == "indeterminate":
            _log.debug("Security: access denied to resources. Error occured when evaluating policies.")
            return False
        else:
            _log.debug("Security: access denied to resources. No matching policies.")
            return False

    def authorize_using_external_server(self, request):
        """
        Access authorization using an external authorization server.

        The request is put in a JSON Web Token (JWT) that is signed
        and includes timestamps and information about sender and receiver.
        """
        ip_addr = self.sec_conf['authorization']['server_ip']
        port = self.sec_conf['authorization']['server_port']
        # Alternative: specify node_id/dnQualifier instead in sec_conf and create a tunnel for the 
        # runtime-to-runtime communication (see calvin_proto.py). Could also add node_id as "aud" (audience) in jwt payload.
        authorization_server_uri = "http://%s:%d" % (ip_addr, port) 
        payload = {
            "iss": self.node.id, 
            "iat": datetime.utcnow(), 
            "exp": datetime.utcnow() + timedelta(seconds=60),
            "request": request
        }
        cert_conffile = _conf.get("security", "certificate_conf")
        domain = _conf.get("security", "certificate_domain")
        cert_conf = certificate.Config(cert_conffile, domain)
        node_name = self.node.attributes.get_node_name_as_str()
        private_key = certificate.get_private_key(cert_conf, node_name)
        # Create a JSON Web Token signed using the node's Elliptic Curve private key.
        jwt_request = jwt.encode(payload, private_key, algorithm='ES256')
        # cert_name is this node's certificate filename (without file extension)
        cert_name = certificate.get_own_cert_name(cert_conf, node_name)
        try:
            # Send request to authorization server.
            response = self.request_handler.get_authorization_decision(authorization_server_uri, jwt_request, cert_name)
        except Exception as e:
            _log.error("Security: authorization server error - %s" % str(e))
            return ("indeterminate", [])
        try:
            # Get authorization server certificate from disk. 
            # TODO: get certificate from DHT if it wasn't found on disk.
            certificate_authz_server = certificate.get_other_certificate(cert_conf, node_name, response["cert_name"])
            public_key_authz_server = certificate.get_public_key(certificate_authz_server)
            authz_server_id = certificate_authz_server.get_subject().dnQualifier
            # Decode the JSON Web Token returned from the authorization server.
            # The signature is verified using the Elliptic Curve public key of the authorization server. 
            # Exception raised if signature verification fails or if issuer and/or audience are incorrect.
            decoded = jwt.decode(response["jwt"], public_key_authz_server, algorithms=['ES256'], 
                                 issuer=authz_server_id, audience=self.node.id)
            response = decoded['response']
            return (response['decision'], response.get("obligations", []))
        except Exception as e:
            _log.error("Security: JWT decoding error - %s" % str(e))
            return ("indeterminate", [])

    def authorize_using_local_policies(self, request):
        """Authorize access using a local Policy Decision Point (PDP)."""
        try:
            response = self.node.pdp.authorize(request)
            return (response['decision'], response.get("obligations", []))
        except Exception as e:
            _log.error("Security: local authorization error - %s" % str(e))
            return ("indeterminate", [])

    @staticmethod
    def verify_signature_get_files(filename, skip_file=False):
        """Get files needed for signature verification of the specified file."""
        # Get the data
        sign_filenames = filename + ".sign.*"
        sign_content = {}
        file_content = ""
        # Filename is *.sign.<cert_hash>
        sign_files = {os.path.basename(f).split(".sign.")[1]: f for f in glob.glob(sign_filenames)}
        for cert_hash, sign_filename in sign_files.iteritems():
            try:
                with open(sign_filename, 'rt') as f:
                    sign_content[cert_hash] = f.read()
                    _log.debug("Security: found signature for %s" % cert_hash)
            except:
                pass
        if not skip_file:
            try:
                with open(filename, 'rt') as f:
                    file_content = f.read()
            except:
                return None
                _log.debug("Security: file can't be opened")
        return {'sign': sign_content, 'file': file_content}

    def verify_signature(self, file, flag):
        """Verify the signature of the specified file of type flag."""
        content = Security.verify_signature_get_files(file)
        if content:
            return self.verify_signature_content(content, flag)
        else:
            return False

    def verify_signature_content(self, content, flag):
        """Verify the signature of the content of type flag."""
        _log.debug("Security: verify %s signature of %s" % (flag, content))
        #if not self.sec_conf:
        #delete:
        if True:
            _log.debug("Security: no signature verification required: %s" % content['file'])
            return True

        if flag not in ["application", "actor"]:
            # TODO add component verification
            raise NotImplementedError

        self.auth[flag + "_signer"] = [True]  # Needed to include the signer attribute in authorization requests.

        if content is None or not content['sign']:
            _log.debug("Security: signature information missing")
            self.subject[flag + "_signer"] = ["__unsigned__"]
            return True  # True is returned to allow authorization request with the signer attribute '__unsigned__'.

        if not HAS_OPENSSL:
            _log.error("Security: install OpenSSL to allow verification of signatures and certificates")
            _log.error("Security: verification of %s signature failed" % flag)
            self.subject[flag + "_signer"] = ["__invalid__"]
            return False

        # If any of the signatures is verified correctly, True is returned.
        for cert_hash, signature in content['sign'].iteritems():
            try:
                # Check if the certificate is stored in the truststore (name is <cert_hash>.0)
                trusted_cert_path = os.path.join(self.sec_conf['signature_trust_store'], cert_hash + ".0")
                with open(trusted_cert_path, 'rt') as f:
                    trusted_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read())
                    try:
                        # Verify signature
                        OpenSSL.crypto.verify(trusted_cert, signature, content['file'], 'sha256')
                        _log.debug("Security: signature correct")
                        self.subject[flag + "_signer"] = [trusted_cert.get_issuer().CN]  # The Common Name field for the issuer
                        return True
                    except Exception as e:
                        _log.debug("Security: OpenSSL verification error", exc_info=True)
                        continue
            except Exception as e:
                _log.debug("Security: error opening one of the needed certificates", exc_info=True)
                continue
        _log.error("Security: verification of %s signature failed" % flag)
        self.subject[flag + "_signer"] = ["__invalid__"]
        return False
 def setUp(self):
     self.request_handler = RequestHandler()
     self.test_type, [self.rt1, self.rt2, self.rt3
                      ] = helpers.setup_test_type(self.request_handler)
Esempio n. 28
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global rt
        global request_handler
        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        try:
            os.makedirs(credentials_testdir)
            os.makedirs(runtimesdir)
            os.makedirs(runtimes_truststore)
            os.makedirs(runtimes_truststore_signing_path)
            os.makedirs(actor_store_path)
            os.makedirs(os.path.join(actor_store_path, "test"))
            shutil.copy(
                os.path.join(orig_actor_store_path, "test", "__init__.py"),
                os.path.join(actor_store_path, "test", "__init__.py"))
            os.makedirs(os.path.join(actor_store_path, "std"))
            shutil.copy(
                os.path.join(orig_actor_store_path, "std", "__init__.py"),
                os.path.join(actor_store_path, "std", "__init__.py"))
            shutil.copytree(orig_application_store_path,
                            application_store_path)
            filelist = [
                f for f in os.listdir(application_store_path)
                if f.endswith(".sign.93d58fef")
            ]
            for f in filelist:
                os.remove(os.path.join(application_store_path, f))
            shutil.copytree(
                os.path.join(security_testdir, "identity_provider"),
                identity_provider_path)
        except Exception as err:
            _log.error(
                "Failed to create test folder structure, err={}".format(err))
            print "Failed to create test folder structure, err={}".format(err)
            raise

        print "Trying to create a new test application/actor signer."
        cs = code_signer.CS(organization="testsigner",
                            commonName="signer",
                            security_dir=credentials_testdir)

        #Create signed version of CountTimer actor
        orig_actor_CountTimer_path = os.path.join(orig_actor_store_path, "std",
                                                  "CountTimer.py")
        actor_CountTimer_path = os.path.join(actor_store_path, "std",
                                             "CountTimer.py")
        shutil.copy(orig_actor_CountTimer_path, actor_CountTimer_path)
        #        cs.sign_file(actor_CountTimer_path)

        #Create unsigned version of CountTimer actor
        actor_CountTimerUnsigned_path = actor_CountTimer_path.replace(
            ".py", "Unsigned.py")
        shutil.copy(actor_CountTimer_path, actor_CountTimerUnsigned_path)
        replace_text_in_file(actor_CountTimerUnsigned_path, "CountTimer",
                             "CountTimerUnsigned")

        #Create signed version of Sum actor
        orig_actor_Sum_path = os.path.join(orig_actor_store_path, "std",
                                           "Sum.py")
        actor_Sum_path = os.path.join(actor_store_path, "std", "Sum.py")
        shutil.copy(orig_actor_Sum_path, actor_Sum_path)
        #        cs.sign_file(actor_Sum_path)

        #Create unsigned version of Sum actor
        actor_SumUnsigned_path = actor_Sum_path.replace(".py", "Unsigned.py")
        shutil.copy(actor_Sum_path, actor_SumUnsigned_path)
        replace_text_in_file(actor_SumUnsigned_path, "Sum", "SumUnsigned")

        #Create incorrectly signed version of Sum actor
        #        actor_SumFake_path = actor_Sum_path.replace(".py", "Fake.py")
        #        shutil.copy(actor_Sum_path, actor_SumFake_path)
        #        #Change the class name to SumFake
        #        replace_text_in_file(actor_SumFake_path, "Sum", "SumFake")
        #        cs.sign_file(actor_SumFake_path)
        #        #Now append to the signed file so the signature verification fails
        #        with open(actor_SumFake_path, "a") as fd:
        #                fd.write(" ")

        #Create signed version of Sink actor
        orig_actor_Sink_path = os.path.join(orig_actor_store_path, "test",
                                            "Sink.py")
        actor_Sink_path = os.path.join(actor_store_path, "test", "Sink.py")
        shutil.copy(orig_actor_Sink_path, actor_Sink_path)
        #        cs.sign_file(actor_Sink_path)

        #Create unsigned version of Sink actor
        actor_SinkUnsigned_path = actor_Sink_path.replace(".py", "Unsigned.py")
        shutil.copy(actor_Sink_path, actor_SinkUnsigned_path)
        replace_text_in_file(actor_SinkUnsigned_path, "Sink", "SinkUnsigned")

        #Sign applications
        #        cs.sign_file(os.path.join(application_store_path, "test_security1_correctly_signed.calvin"))
        #        cs.sign_file(os.path.join(application_store_path, "test_security1_correctlySignedApp_incorrectlySignedActor.calvin"))
        #        cs.sign_file(os.path.join(application_store_path, "test_security1_incorrectly_signed.calvin"))
        #        #Now append to the signed file so the signature verification fails
        #        with open(os.path.join(application_store_path, "test_security1_incorrectly_signed.calvin"), "a") as fd:
        #                fd.write(" ")

        #        print "Export Code Signers certificate to the truststore for code signing"
        #        out_file = cs.export_cs_cert(runtimes_truststore_signing_path)

        print "Trying to create a new test domain configuration."
        ca = certificate_authority.CA(domain=domain_name,
                                      commonName="testdomain CA",
                                      security_dir=credentials_testdir)
        #
        print "Copy CA cert into truststore of runtimes folder"
        ca.export_ca_cert(runtimes_truststore)
        #Define the runtime attributes
        rt0_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'CA'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt1_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode1'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt2_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode2'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'otherStreet',
                    'streetNumber': 1
                }
            }
        }
        rt3_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode3'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt4_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode4'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt5_attributes = {
            'indexed_public': {
                'owner': {
                    'organization': domain_name,
                    'personOrGroup': 'testOwner1'
                },
                'node_name': {
                    'organization': 'org.testexample',
                    'name': 'testNode5'
                },
                'address': {
                    'country': 'SE',
                    'locality': 'testCity',
                    'street': 'testStreet',
                    'streetNumber': 1
                }
            }
        }
        rt_attributes = []
        rt_attributes.append(deepcopy(rt0_attributes))
        rt_attributes.append(deepcopy(rt1_attributes))
        rt_attributes.append(deepcopy(rt2_attributes))
        rt_attributes.append(deepcopy(rt3_attributes))
        rt_attributes.append(deepcopy(rt4_attributes))
        rt_attributes.append(deepcopy(rt5_attributes))
        rt_attributes_cpy = deepcopy(rt_attributes)
        runtimes = []
        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(
            type=certificate.TRUSTSTORE_TRANSPORT,
            security_dir=credentials_testdir)
        #   The following is less than optimal if multiple CA certs exist
        ca_cert_path = os.path.join(truststore_dir,
                                    os.listdir(truststore_dir)[0])
        request_handler = RequestHandler(verify=ca_cert_path)
        #Generate credentials, create CSR, sign with CA and import cert for all runtimes
        enrollment_passwords = []
        for rt_attribute in rt_attributes:
            attributes = AttributeResolver(rt_attribute)
            node_name = attributes.get_node_name_as_str()
            nodeid = calvinuuid.uuid("")
            enrollment_password = ca.cert_enrollment_add_new_runtime(node_name)
            enrollment_passwords.append(enrollment_password)
            runtime = runtime_credentials.RuntimeCredentials(
                node_name,
                domain=domain_name,
                security_dir=credentials_testdir,
                nodeid=nodeid,
                enrollment_password=enrollment_password)
            runtimes.append(runtime)
            ca_cert = runtime.get_truststore(
                type=certificate.TRUSTSTORE_TRANSPORT)[0][0]
            csr_path = os.path.join(runtime.runtime_dir, node_name + ".csr")
            #Encrypt CSR with CAs public key (to protect enrollment password)
            rsa_encrypted_csr = runtime.cert_enrollment_encrypt_csr(
                csr_path, ca_cert)
            #Decrypt encrypted CSR with CAs private key
            csr = ca.decrypt_encrypted_csr(
                encrypted_enrollment_request=rsa_encrypted_csr)
            csr_path = ca.store_csr_with_enrollment_password(csr)
            cert_path = ca.sign_csr(csr_path)
            runtime.store_own_cert(certpath=cert_path,
                                   security_dir=credentials_testdir)
        #Let's hash passwords in users.json file (the runtimes will try to do this
        # but they will all try to do it at the same time, so it will be overwritten
        # multiple times and the first test will always fail)
#        self.arp = FileAuthenticationRetrievalPoint(identity_provider_path)
#        self.arp.check_stored_users_db_for_unhashed_passwords()

#The policy allows access to control interface for everyone, for more advanced rules
# it might be appropriate to run set_credentials for request_handler, e.g.,
#  request_handler.set_credentials({domain_name:{"user": "******", "password": "******"}})

        rt_conf = copy.deepcopy(_conf)
        #        rt_conf.set('security', 'runtime_to_runtime_security', "tls")
        #        rt_conf.set('security', 'control_interface_security', "tls")
        rt_conf.set('security', 'domain_name', domain_name)
        #        rt_conf.set('security', 'certificate_authority_control_uri',"https://%s:5020" % hostname )
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt_conf.set('global', 'actor_paths', [actor_store_path])
        rt_conf.set('global', 'storage_type', "securedht")

        # Runtime 0: local authentication, signature verification, local authorization.
        # Primarily acts as Certificate Authority for the domain
        rt0_conf = copy.deepcopy(rt_conf)
        #        rt0_conf.set('security','enrollment_password',enrollment_passwords[0])
        #The csruntime certificate requests assumes TLS for the control interface
        #        rt0_conf.set('security', 'control_interface_security', "tls")
        #        rt0_conf.set('security','certificate_authority','True')
        #        rt0_conf.set("security", "security_conf", {
        #                        "comment": "Certificate Authority",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt0_conf.save("/tmp/calvin5000.conf")

        # Runtime 1: local authentication, signature verification, local authorization.
        rt1_conf = copy.deepcopy(rt_conf)
        #        rt1_conf.set('security','enrollment_password',enrollment_passwords[1])
        #        rt1_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, local authorization",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt1_conf.save("/tmp/calvin5001.conf")

        # Runtime 2: local authentication, signature verification, local authorization.
        # Can also act as authorization server for other runtimes.
        # Other street compared to the other runtimes
        rt2_conf = copy.deepcopy(rt_conf)
        #        rt2_conf.set('security','enrollment_password',enrollment_passwords[2])
        #        rt2_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, local authorization",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path,
        #                            "accept_external_requests": True
        #                        }
        #                    })
        rt2_conf.save("/tmp/calvin5002.conf")

        # Runtime 3: external authentication (RADIUS), signature verification, local authorization.
        rt3_conf = copy.deepcopy(rt_conf)
        #        rt3_conf.set('security','enrollment_password',enrollment_passwords[3])
        #        rt3_conf.set("security", "security_conf", {
        #                        "comment": "RADIUS authentication, local authorization",
        #                        "authentication": {
        #                            "procedure": "radius",
        #                            "server_ip": "localhost",
        #                            "secret": "elxghyc5lz1_passwd"
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt3_conf.save("/tmp/calvin5003.conf")

        # Runtime 4: local authentication, signature verification, external authorization (runtime 2).
        rt4_conf = copy.deepcopy(rt_conf)
        #        rt4_conf.set('security','enrollment_password',enrollment_passwords[4])
        #        rt4_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, external authorization",
        #                        "authentication": {
        #                            "procedure": "local",
        #                            "identity_provider_path": identity_provider_path
        #                        },
        #                        "authorization": {
        #                            "procedure": "external"
        #                        }
        #                    })
        rt4_conf.save("/tmp/calvin5004.conf")

        # Runtime 5: external authentication (runtime 1), signature verification, local authorization.
        rt5_conf = copy.deepcopy(rt_conf)
        #        rt5_conf.set('global','storage_type','proxy')
        #        rt5_conf.set('global','storage_proxy',"calvinip://%s:5000" % ip_addr )
        #        rt5_conf.set('security','enrollment_password',enrollment_passwords[5])
        #        rt5_conf.set("security", "security_conf", {
        #                        "comment": "Local authentication, external authorization",
        #                        "authentication": {
        #                            "procedure": "external",
        #                            "server_uuid": runtimes[1].node_id
        #                        },
        #                        "authorization": {
        #                            "procedure": "local",
        #                            "policy_storage_path": policy_storage_path
        #                        }
        #                    })
        rt5_conf.save("/tmp/calvin5005.conf")

        #Start all runtimes
        for i in range(len(rt_attributes_cpy)):
            _log.info("Starting runtime {}".format(i))
            try:
                logfile = _config_pytest.getoption("logfile") + "500{}".format(
                    i)
                outfile = os.path.join(
                    os.path.dirname(logfile),
                    os.path.basename(logfile).replace("log", "out"))
                if outfile == logfile:
                    outfile = None
            except:
                logfile = None
                outfile = None
            csruntime(hostname,
                      port=5000 + i,
                      controlport=5020 + i,
                      attr=rt_attributes_cpy[i],
                      loglevel=_config_pytest.getoption("loglevel"),
                      logfile=logfile,
                      outfile=outfile,
                      configfile="/tmp/calvin500{}.conf".format(i))
            #            rt.append(RT("https://{}:502{}".format(hostname, i)))
            rt.append(RT("http://{}:502{}".format(hostname, i)))
            # Wait to be sure that all runtimes has started
            time.sleep(1)
        time.sleep(10)

        request.addfinalizer(self.teardown)
Esempio n. 29
0
import shutil
import json
from collections import namedtuple
from calvin.requests.request_handler import RequestHandler, RT
from calvin.utilities.nodecontrol import dispatch_node, dispatch_storage_node
from calvin.utilities.attribute_resolver import format_index_string
from calvin.utilities import certificate
from calvin.utilities import certificate_authority
from calvin.utilities import calvinlogger
from calvin.utilities import calvinconfig
from calvin.utilities import calvinuuid
from calvin.utilities.utils import get_home

_log = calvinlogger.get_logger(__name__)
_conf = calvinconfig.get()
request_handler = RequestHandler()

try:
    ip_addr = os.environ["CALVIN_TEST_LOCALHOST"]
except:
    ip_addr = socket.gethostbyname(socket.gethostname())

rt1 = None
rt2 = None
rt3 = None
rt1_id = None
rt2_id = None
rt3_id = None
test_script_dir = None

deploy_attr = [
Esempio n. 30
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global hostname
        global rt
        global rt_attributes
        global request_handler
        try:
            ipv6_hostname = socket.gethostbyaddr('::1')
        except Exception as err:
            print(
                "Failed to resolve the IPv6 localhost hostname, please update the corresponding entry in the /etc/hosts file, e.g.,:\n"
                "\t::1              <hostname>.localdomain <hostname>.local <hostname> localhost"
            )
            raise
        try:
            ipv6_hostname = socket.gethostbyaddr('::ffff:127.0.0.1')
        except Exception as err:
            print(
                "Failed to resolve ::ffff:127.0.0.1, please add the following line (with your hostname) to  /etc/hosts :\n"
                "::ffff:127.0.0.1:           <hostname>.localdomain <hostname>.local <hostname>"
            )
            raise
        try:
            hostname = socket.gethostname()
            ip_addr = socket.gethostbyname(hostname)
            fqdn = socket.getfqdn(hostname)
            print("\n\tip_addr={}"
                  "\n\thostname={}"
                  "\n\tfqdn={}".format(ip_addr, hostname, fqdn))
        except Exception as err:
            print(
                "Failed to resolve the hostname, ip_addr or the FQDN of the runtime, err={}"
                .format(err))
            raise

        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        try:
            os.makedirs(credentials_testdir)
            os.makedirs(runtimesdir)
            os.makedirs(runtimes_truststore)
        except Exception as err:
            _log.error(
                "Failed to create test folder structure, err={}".format(err))
            print "Failed to create test folder structure, err={}".format(err)
            raise

        _log.info(
            "Trying to create a new test domain configuration. Create many CAs to ensure runtime can handle several CA certificates"
        )
        try:
            ca1 = certificate_authority.CA(domain=domain_name + " 1",
                                           commonName="testdomainCA1",
                                           security_dir=credentials_testdir)
            ca2 = certificate_authority.CA(domain=domain_name + " 2",
                                           commonName="testdomainCA2",
                                           security_dir=credentials_testdir)
            ca3 = certificate_authority.CA(domain=domain_name + " 3",
                                           commonName="testdomainCA3",
                                           security_dir=credentials_testdir)
        except Exception as err:
            _log.error("Failed to create CA, err={}".format(err))

        _log.info("Copy CA cert into truststore of runtimes folder")
        ca1.export_ca_cert(runtimes_truststore)
        ca2.export_ca_cert(runtimes_truststore)
        ca3.export_ca_cert(runtimes_truststore)

        actor_store_path, application_store_path = helpers.sign_files_for_security_tests(
            credentials_testdir)
        runtimes = helpers.create_CA_and_generate_runtime_certs(
            domain_name, credentials_testdir, NBR_OF_RUNTIMES)
        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(
            type=certificate.TRUSTSTORE_TRANSPORT,
            security_dir=credentials_testdir)
        request_handler = RequestHandler(verify=truststore_dir)

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'runtime_to_runtime_security', "tls")
        rt_conf.set('security', 'control_interface_security', "tls")
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt0_conf = copy.deepcopy(rt_conf)

        # Runtime 0: local authentication, signature verification, local authorization.
        # Primarily acts as Certificate Authority for the domain
        rt0_conf.set('global', 'storage_type', 'local')
        rt0_conf.set('security', 'certificate_authority', {
            'domain_name': domain_name,
            'is_ca': 'True'
        })
        rt0_conf.save("/tmp/calvin5000.conf")

        # Runtime 1: local authentication, signature verification, local authorization.
        rt_conf.set('global', 'storage_type', 'proxy')
        rt_conf.set('global', 'storage_proxy', "calvinip://%s:5000" % hostname)
        rt_conf.set('security', 'certificate_authority', {
            'domain_name': domain_name,
            'is_ca': 'False'
        })

        for i in range(1, NBR_OF_RUNTIMES):
            rt_conf.save("/tmp/calvin500{}.conf".format(i))

        rt = helpers.start_all_runtimes(runtimes,
                                        hostname,
                                        request_handler,
                                        tls=True)
        request.addfinalizer(self.teardown)
Esempio n. 31
0
def runtime_certificate(rt_attributes):
    import copy
    import requests
    import sys
    from calvin.requests.request_handler import RequestHandler
    from calvin.utilities.attribute_resolver import AttributeResolver
    from calvin.utilities import calvinconfig
    from calvin.utilities import calvinuuid
    from calvin.utilities import runtime_credentials
    from calvin.utilities import certificate
    from calvin.utilities import certificate_authority
    from calvin.runtime.south.storage.twistedimpl.dht.service_discovery_ssdp import parse_http_response
    global _conf
    global _log
    _conf = calvinconfig.get()
    if not _conf.get_section("security"):
        #If the security section is empty, no securty features are enabled and certificates aren't needed
        _log.debug("No runtime security enabled")
    else:
        _log.debug("Some security features are enabled, let's make sure certificates are in place")
        _ca_conf = _conf.get("security","certificate_authority")
        security_dir = _conf.get("security","security_dir")
        storage_type = _conf.get("global","storage_type")
        if _ca_conf:
            try:
                ca_ctrl_uri = _ca_conf["ca_control_uri"] if "ca_control_uri" in _ca_conf else None
                domain_name = _ca_conf["domain_name"] if "domain_name" in _ca_conf else None
                is_ca = _ca_conf["is_ca"] if "is_ca" in _ca_conf else None
                enrollment_password =  _ca_conf["enrollment_password"] if "enrollment_password" in _ca_conf else None
            except Exception as err:
                _log.error("runtime_certificate: Failed to parse security configuration in calvin.conf, err={}".format(err))
                raise
            #AttributeResolver tranforms the attributes, so make a deepcopy instead
            rt_attributes_cpy = copy.deepcopy(rt_attributes)
            attributes = AttributeResolver(rt_attributes_cpy)
            node_name = attributes.get_node_name_as_str()
            nodeid = calvinuuid.uuid("")
            runtime = runtime_credentials.RuntimeCredentials(node_name, domain_name,
                                                           security_dir=security_dir,
                                                           nodeid=nodeid,
                                                           enrollment_password=enrollment_password)
            certpath, cert, certstr = runtime.get_own_cert()
            if not cert:
                csr_path = os.path.join(runtime.runtime_dir, node_name + ".csr")
                if is_ca:
                    _log.debug("No runtime certificate, but node is a CA, just sign csr, domain={}".format(domain_name))
                    ca = certificate_authority.CA(domain=domain_name,
                                                  security_dir=security_dir)
                    cert_path = ca.sign_csr(csr_path, is_ca=True)
                    runtime.store_own_cert(certpath=cert_path)

                else:
                    _log.debug("No runtime certicificate can be found, send CSR to CA")
                    truststore_dir = certificate.get_truststore_path(type=certificate.TRUSTSTORE_TRANSPORT,
                                                                     security_dir=security_dir)
                    request_handler = RequestHandler(verify=truststore_dir)
                    ca_control_uris = []
                    #TODO: add support for multiple CA control uris
                    if ca_ctrl_uri:
                        _log.debug("CA control_uri in config={}".format(ca_ctrl_uri))
                        ca_control_uris.append(ca_ctrl_uri)
                    elif storage_type in ["dht","securedht"]:
                        _log.debug("Find CA via SSDP")
                        responses = discover()
                        if not responses:
                            _log.error("No responses received")
                        for response in responses:
                            cmd, headers = parse_http_response(response)
                            if 'location' in headers:
                                ca_control_uri, ca_node_id = headers['location'].split('/node/')
                                ca_control_uris.append(ca_control_uri)
                                _log.debug("CA control_uri={}, node_id={}".format(ca_control_uri, ca_node_id))
                    else:
                        _log.error("There is no runtime certificate. For automatic certificate enrollment using proxy storage,"
                                        "the CA control uri must be configured in the calvin configuration ")
                        raise Exception("There is no runtime certificate. For automatic certificate enrollment using proxy storage,"
                                        "the CA control uri must be configured in the calvin configuration ")
                    cert_available=False
                    # Loop through all CA:s that responded until hopefully one signs our CSR
                    # Potential improvement would be to have domain name in response and only try
                    # appropriate CAs
                    i=0
                    csr = json.dumps(runtime.get_csr_and_enrollment_password())
                    while not cert_available and i<len(ca_control_uris):
                        certstr=None
                        #Repeatedly (maximum 10 attempts) send CSR to CA until a certificate is returned (this to remove the requirement of the CA
                        #node to be be the first node to start)
                        j=0
                        while not certstr and j<10:
                            try:
                                certstr = request_handler.sign_csr_request(ca_control_uris[i], csr)['certificate']
                            except requests.exceptions.RequestException as err:
                                time_to_sleep = 1 + j*j*j
                                _log.debug("RequestException, CSR not accepted or CA not up and running yet, sleep {} seconds and try again, err={}".format(time_to_sleep, err))
                                time.sleep(time_to_sleep)
                                j=j+1
                                pass
                            else:
                                cert_available = True
                        i = i+1
                    #TODO: check that everything is ok with signed cert, e.g., check that the CA domain
                    # matches the expected and that the CA cert is trusted
                    runtime.store_own_cert(certstring=certstr)
            else:
                _log.debug("Runtime certificate available")
Esempio n. 32
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global runtimes
        global request_handler
        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        try:
            shutil.copytree(orig_identity_provider_path, identity_provider_path)
        except Exception as err:
            _log.error("Failed to copy the identity provider files, err={}".format(err))
            raise
        actor_store_path, application_store_path = helpers.sign_files_for_security_tests(credentials_testdir)
        runtimes = helpers.create_CA_and_generate_runtime_certs(domain_name, credentials_testdir, NBR_OF_RUNTIMES)

        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(type=certificate.TRUSTSTORE_TRANSPORT, 
                                                         security_dir=credentials_testdir)
        request_handler = RequestHandler(verify=truststore_dir)
        #Let's use the admin user0 for request_handler
        request_handler.set_credentials({"user": "******", "password": "******"})

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt_conf.set('global', 'actor_paths', [actor_store_path])

        # Runtime 0: Certificate authority, authentication server, authorization server.
        rt0_conf = copy.deepcopy(rt_conf)
        rt0_conf.set('global','storage_type','local')
        rt0_conf.set('security','certificate_authority',{
            'domain_name':domain_name,
            'is_ca':True
            })
        rt0_conf.set("security", "security_conf", {
                        "comment": "Certificate Authority",
                        "authentication": {
                            "procedure": "local",
                            "identity_provider_path": identity_provider_path,
                            "accept_external_requests": True
                        },
                        "authorization": {
                            "procedure": "local",
                            "policy_storage_path": policy_storage_path,
                            "accept_external_requests": True
                        }
                    })
        rt0_conf.save("/tmp/calvin5000.conf")

        _log.info("Starting runtime 0")

        # Other runtimes
        rt_conf.set('global','storage_type','proxy')
        rt_conf.set('global','storage_proxy',"calvinip://%s:5000" % ip_addr )
        rt_conf.set('security','certificate_authority',{
            'domain_name':domain_name,
            'is_ca':False
        })
        rt_conf.set("security", "security_conf", {
                        "comment": "External authentication, external authorization",
                        "authentication": {
                            "procedure": "external",
                            "server_uuid": runtimes[0]["id"]
                        },
                        "authorization": {
                            "procedure": "external",
                            "server_uuid": runtimes[0]["id"]
                        }
                    })

        for i in range(1, NBR_OF_RUNTIMES):
            rt_conf.save("/tmp/calvin500{}.conf".format(i))

#        # Runtime 3: external authentication (RADIUS).
#        rt3_conf = copy.deepcopy(rt1_conf)
#        rt3_conf.set('security','enrollment_password',enrollment_passwords[3])
#        rt3_conf.save("/tmp/calvin5002.conf")
#        rt3_conf.set("security", "security_conf", {
#                        "authentication": {
#                            "procedure": "radius",
#                            "server_ip": "localhost",
#                            "secret": "elxghyc5lz1_passwd"
#                        },
#                        "authorization": {
#                            "procedure": "external",
#                            "server_uuid": runtimes[0].node_id
#                        }
#                    })
#        rt3_conf.save("/tmp/calvin5003.conf")

        helpers.start_all_runtimes(runtimes, hostname, request_handler)
        request.addfinalizer(self.teardown)
Esempio n. 33
0
    def setup(self, request):
        from calvin.Tools.csruntime import csruntime
        from conftest import _config_pytest
        import fileinput
        global hostname
        global rt
        global rt_attributes
        global request_handler
        try:
            ipv6_hostname = socket.gethostbyaddr('::1')
        except Exception as err:
            print(
                "Failed to resolve the IPv6 localhost hostname, please update the corresponding entry in the /etc/hosts file, e.g.,:\n"
                "\t::1              <hostname>.localdomain <hostname>.local <hostname> localhost"
            )
            raise
        try:
            ipv6_hostname = socket.gethostbyaddr('::ffff:127.0.0.1')
        except Exception as err:
            print(
                "Failed to resolve ::ffff:127.0.0.1, please add the following line (with your hostname) to  /etc/hosts :\n"
                "::ffff:127.0.0.1:           <hostname>.localdomain <hostname>.local <hostname>"
            )
            raise
        try:
            hostname = socket.gethostname()
            ip_addr = socket.gethostbyname(hostname)
            fqdn = socket.getfqdn(hostname)
            print("\n\tip_addr={}"
                  "\n\thostname={}"
                  "\n\tfqdn={}".format(ip_addr, hostname, fqdn))
        except Exception as err:
            print(
                "Failed to resolve the hostname, ip_addr or the FQDN of the runtime, err={}"
                .format(err))
            raise

        try:
            shutil.rmtree(credentials_testdir)
        except Exception as err:
            print "Failed to remove old tesdir, err={}".format(err)
            pass
        try:
            os.mkdir(credentials_testdir)
            os.mkdir(runtimesdir)
            os.mkdir(runtimes_truststore)
        except Exception as err:
            _log.error(
                "Failed to create test folder structure, err={}".format(err))
            print "Failed to create test folder structure, err={}".format(err)
            raise

        _log.info("Trying to create a new test domain configuration.")
        try:
            ca = certificate_authority.CA(domain=domain_name,
                                          commonName="testdomain CA",
                                          security_dir=credentials_testdir)
        except Exception as err:
            _log.error("Failed to create CA, err={}".format(err))

        _log.info("Copy CA cert into truststore of runtimes folder")
        ca.export_ca_cert(runtimes_truststore)
        node_names = []
        rt_attributes = []
        for i in range(6):
            node_name = {
                'organization': 'org.testexample',
                'name': 'testNode{}'.format(i)
            }
            owner = {'organization': domain_name, 'personOrGroup': 'testOwner'}
            address = {
                'country': 'SE',
                'locality': 'testCity',
                'street': 'testStreet',
                'streetNumber': 1
            }
            rt_attribute = {
                'indexed_public': {
                    'owner': owner,
                    'node_name': node_name,
                    'address': address
                }
            }
            rt_attributes.append(rt_attribute)
        rt_attributes_cpy = deepcopy(rt_attributes)
        runtimes = []
        #Initiate Requesthandler with trusted CA cert
        truststore_dir = certificate.get_truststore_path(
            type=certificate.TRUSTSTORE_TRANSPORT,
            security_dir=credentials_testdir)
        #   The following is less than optimal if multiple CA certs exist
        ca_cert_path = os.path.join(truststore_dir,
                                    os.listdir(truststore_dir)[0])
        request_handler = RequestHandler(verify=ca_cert_path)

        #Generate credentials, create CSR, sign with CA and import cert for all runtimes
        enrollment_passwords = []
        for rt_attribute in rt_attributes_cpy:
            _log.info("rt_attribute={}".format(rt_attribute))
            attributes = AttributeResolver(rt_attribute)
            node_name = attributes.get_node_name_as_str()
            nodeid = calvinuuid.uuid("")
            enrollment_password = ca.cert_enrollment_add_new_runtime(node_name)
            enrollment_passwords.append(enrollment_password)
            runtime = runtime_credentials.RuntimeCredentials(
                node_name,
                domain=domain_name,
                security_dir=credentials_testdir,
                nodeid=nodeid,
                enrollment_password=enrollment_password)
            runtimes.append(runtime)
            ca_cert = runtime.get_truststore(
                type=certificate.TRUSTSTORE_TRANSPORT)[0][0]
            csr_path = os.path.join(runtime.runtime_dir, node_name + ".csr")
            #Encrypt CSR with CAs public key (to protect enrollment password)
            rsa_encrypted_csr = runtime.cert_enrollment_encrypt_csr(
                csr_path, ca_cert)
            #Decrypt encrypted CSR with CAs private key
            csr = ca.decrypt_encrypted_csr(
                encrypted_enrollment_request=rsa_encrypted_csr)
            csr_path = ca.store_csr_with_enrollment_password(csr)
            cert_path = ca.sign_csr(csr_path)
            runtime.store_own_cert(certpath=cert_path,
                                   security_dir=credentials_testdir)

        rt_conf = copy.deepcopy(_conf)
        rt_conf.set('security', 'runtime_to_runtime_security', "tls")
        rt_conf.set('security', 'control_interface_security', "tls")
        rt_conf.set('security', 'domain_name', domain_name)
        rt_conf.set('security', 'security_dir', credentials_testdir)
        rt0_conf = copy.deepcopy(rt_conf)
        rt_conf.set('global', 'storage_type', 'proxy')
        rt_conf.set('global', 'storage_proxy', "calvinip://%s:5000" % hostname)

        # Runtime 0: local authentication, signature verification, local authorization.
        # Primarily acts as Certificate Authority for the domain
        rt0_conf.set('global', 'storage_type', 'local')
        rt0_conf.save("/tmp/calvin5000.conf")

        # Runtime 1: local authentication, signature verification, local authorization.
        rt1_conf = copy.deepcopy(rt_conf)
        rt1_conf.save("/tmp/calvin5001.conf")

        # Runtime 2: local authentication, signature verification, local authorization.
        # Can also act as authorization server for other runtimes.
        # Other street compared to the other runtimes
        rt2_conf = copy.deepcopy(rt_conf)
        rt2_conf.save("/tmp/calvin5002.conf")

        # Runtime 3: external authentication (RADIUS), signature verification, local authorization.
        rt3_conf = copy.deepcopy(rt_conf)
        rt3_conf.save("/tmp/calvin5003.conf")

        # Runtime 4: local authentication, signature verification, external authorization (runtime 2).
        rt4_conf = copy.deepcopy(rt_conf)
        rt4_conf.save("/tmp/calvin5004.conf")

        # Runtime 5: external authentication (runtime 1), signature verification, local authorization.
        rt5_conf = copy.deepcopy(rt_conf)
        rt5_conf.save("/tmp/calvin5005.conf")

        #Start all runtimes
        for i in range(len(rt_attributes)):
            _log.info("Starting runtime {}".format(i))
            try:
                logfile = _config_pytest.getoption("logfile") + "500{}".format(
                    i)
                outfile = os.path.join(
                    os.path.dirname(logfile),
                    os.path.basename(logfile).replace("log", "out"))
                if outfile == logfile:
                    outfile = None
            except:
                logfile = None
                outfile = None
            csruntime(hostname,
                      port=5000 + i,
                      controlport=5020 + i,
                      attr=rt_attributes[i],
                      loglevel=_config_pytest.getoption("loglevel"),
                      logfile=logfile,
                      outfile=outfile,
                      configfile="/tmp/calvin500{}.conf".format(i))
            rt.append(RT("https://{}:502{}".format(hostname, i)))
            # Wait to be sure that all runtimes has started
            time.sleep(1)
        time.sleep(2)

        request.addfinalizer(self.teardown)
 def setUp(self):
     self.request_handler = RequestHandler()
     self.test_type, [self.rt1, self.rt2, self.rt3] = helpers.setup_test_type(self.request_handler)
Esempio n. 35
0
def setup_module(module):
    global runtime
    global runtimes
    global peerlist
    global kill_peers
    global request_handler
    ip_addr = None
    bt_master_controluri = None

    request_handler = RequestHandler()
    try:
        ip_addr = os.environ["CALVIN_TEST_IP"]
        purpose = os.environ["CALVIN_TEST_UUID"]
    except KeyError:
        pass

    if ip_addr is None:
        # Bluetooth tests assumes one master runtime with two connected peers
        # CALVIN_TEST_BT_MASTERCONTROLURI is the control uri of the master runtime
        try:
            bt_master_controluri = os.environ["CALVIN_TEST_BT_MASTERCONTROLURI"]
            _log.debug("Running Bluetooth tests")
        except KeyError:
            pass

    if ip_addr:
        remote_node_count = 2
        kill_peers = False
        test_peers = None


        import socket
        ports=[]
        for a in range(2):
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.bind(('', 0))
            addr = s.getsockname()
            ports.append(addr[1])
            s.close()

        runtime,_ = dispatch_node(["calvinip://%s:%s" % (ip_addr, ports[0])], "http://%s:%s" % (ip_addr, ports[1]))

        _log.debug("First runtime started, control http://%s:%s, calvinip://%s:%s" % (ip_addr, ports[1], ip_addr, ports[0]))

        interval = 0.5
        for retries in range(1,20):
            time.sleep(interval)
            _log.debug("Trying to get test nodes for 'purpose' %s" % purpose)
            test_peers = request_handler.get_index(runtime, format_index_string({'node_name':
                                                                         {'organization': 'com.ericsson',
                                                                          'purpose': purpose}
                                                                      }))
            if not test_peers is None and not test_peers["result"] is None and \
                    len(test_peers["result"]) == remote_node_count:
                test_peers = test_peers["result"]
                break

        if test_peers is None or len(test_peers) != remote_node_count:
            _log.debug("Failed to find all remote nodes within time, peers = %s" % test_peers)
            raise Exception("Not all nodes found dont run tests, peers = %s" % test_peers)

        test_peer2_id = test_peers[0]
        test_peer2 = request_handler.get_node(runtime, test_peer2_id)
        if test_peer2:
            runtime2 = RT(test_peer2["control_uri"])
            runtime2.id = test_peer2_id
            runtime2.uri = test_peer2["uri"]
            runtimes.append(runtime2)
        test_peer3_id = test_peers[1]
        if test_peer3_id:
            test_peer3 = request_handler.get_node(runtime, test_peer3_id)
            if test_peer3:
                runtime3 = RT(test_peer3["control_uri"])
                runtime3.id = test_peer3_id
                runtime3.uri = test_peer3["uri"]
                runtimes.append(runtime3)
    elif bt_master_controluri:
        runtime = RT(bt_master_controluri)
        bt_master_id = request_handler.get_node_id(bt_master_controluri)
        data = request_handler.get_node(runtime, bt_master_id)
        if data:
            runtime.id = bt_master_id
            runtime.uri = data["uri"]
            test_peers = request_handler.get_nodes(runtime)
            test_peer2_id = test_peers[0]
            test_peer2 = request_handler.get_node(runtime, test_peer2_id)
            if test_peer2:
                rt2 = RT(test_peer2["control_uri"])
                rt2.id = test_peer2_id
                rt2.uri = test_peer2["uri"]
                runtimes.append(rt2)
            test_peer3_id = test_peers[1]
            if test_peer3_id:
                test_peer3 = request_handler.get_node(runtime, test_peer3_id)
                if test_peer3:
                    rt3 = request_handler.RT(test_peer3["control_uri"])
                    rt3.id = test_peer3_id
                    rt3.uri = test_peer3["uri"]
                    runtimes.append(rt3)
    else:
        try:
            ip_addr = os.environ["CALVIN_TEST_LOCALHOST"]
        except:
            import socket
            ip_addr = socket.gethostbyname(socket.gethostname())
        localhost = "calvinip://%s:5000" % (ip_addr,), "http://localhost:5001"
        remotehosts = [("calvinip://%s:%d" % (ip_addr, d), "http://localhost:%d" % (d+1)) for d in range(5002, 5005, 2)]
        # remotehosts = [("calvinip://127.0.0.1:5002", "http://localhost:5003")]

        for host in remotehosts:
            runtimes += [dispatch_node([host[0]], host[1])[0]]

        runtime, _ = dispatch_node([localhost[0]], localhost[1])

        time.sleep(1)

        # FIXME When storage up and running peersetup not needed, but still useful during testing
        request_handler.peer_setup(runtime, [i[0] for i in remotehosts])

        time.sleep(0.5)
        """

        # FIXME Does not yet support peerlist
        try:
            self.peerlist = peerlist(
                self.runtime, self.runtime.id, len(remotehosts))

            # Make sure all peers agree on network
            [peerlist(self.runtime, p, len(self.runtimes)) for p in self.peerlist]
        except:
            self.peerlist = []
        """

    peerlist = [rt.control_uri for rt in runtimes]
    print "SETUP DONE ***", peerlist