Beispiel #1
0
 def __init__(self, io_threads=1, shared_secret=None):
     zmq.Context.__init__(self, io_threads)
     if shared_secret is not None:
         _check_versions()
         keys = _unpack_shared_secret(shared_secret)
         self.client_secretkey, self.server_secretkey = keys
         self.client_publickey = zmq.curve_public(self.client_secretkey)
         self.server_publickey = zmq.curve_public(self.server_secretkey)
         # Don't hold ref to auth: needed for auto cleanup at shutdown:
         auth = zmq.auth.thread.ThreadAuthenticator(self)
         auth.start()
         # Allow only clients who have the client public key:
         auth.thread.authenticator.allow_any = False
         auth.thread.authenticator.certs['*'] = {
             self.client_publickey: True
         }
         self.secure = True
Beispiel #2
0
def generate_zmq_public_key(key_private):
    """
    Generates public key based on private key for ZMQ encryption.

    Returns
    -------
    str
        Public key.
    """
    key_public = zmq.curve_public(key_private.encode("utf-8"))
    return key_public.decode("utf-8")
    def test_curve_public(self):
        """test curve_public"""
        try:
            public, secret = zmq.curve_keypair()
        except zmq.ZMQError:
            raise SkipTest("CURVE unsupported")
        if zmq.zmq_version_info() < (4, 2):
            raise SkipTest("curve_public is new in libzmq 4.2")

        derived_public = zmq.curve_public(secret)

        self.assertEqual(type(derived_public), bytes)
        self.assertEqual(len(derived_public), 40)

        # verify that it is indeed Z85
        bpublic = z85.decode(derived_public)
        self.assertEqual(type(bpublic), bytes)
        self.assertEqual(len(bpublic), 32)

        # verify that it is equal to the known public key
        self.assertEqual(derived_public, public)
Beispiel #4
0
    def test_curve_public(self):
        """test curve_public"""
        try:
            public, secret = zmq.curve_keypair()
        except zmq.ZMQError:
            raise SkipTest("CURVE unsupported")
        if zmq.zmq_version_info() < (4,2):
            raise SkipTest("curve_public is new in libzmq 4.2")

        derived_public = zmq.curve_public(secret)

        self.assertEqual(type(derived_public), bytes)
        self.assertEqual(len(derived_public), 40)

        # verify that it is indeed Z85
        bpublic = z85.decode(derived_public)
        self.assertEqual(type(bpublic), bytes)
        self.assertEqual(len(bpublic), 32)

        # verify that it is equal to the known public key
        self.assertEqual(derived_public, public)
Beispiel #5
0
    def __init__(self, gModel, gModelName, dName, qName, sysArgv):
        '''
        Constructor
        
        :param dName: device type name
        :type dName: str
        
        :param qName: qualified name of the device instance: 'actor.inst'
        :type qName: str
         
        '''
        self.logger = logging.getLogger(__name__)
        self.inst_ = self
        self.appName = gModel["name"]
        self.modelName = gModelName
        aName,iName = qName.split('.')
        self.name = qName
        self.iName = iName
        self.dName = dName 
        self.pid = os.getpid()
        self.uuid = None
        self.suffix = ""
        self.setupIfaces()
        # Assumption : pid is a 4 byte int
        self.actorID = ipaddress.IPv4Address(self.globalHost).packed + self.pid.to_bytes(4, 'big')
        if dName not in gModel["devices"]:
            raise BuildError('Device "%s" unknown' % dName)
       
        # In order to make the rest of the code work, we build an actor model for the device
        devModel = gModel["devices"][dName]
        self.model = {}  # The made-up actor model
        
        formals = devModel["formals"]  # Formals are the same as those of the device (component)
        self.model["formals"] = formals

        devInst = { "type": dName }  # There is a single instance, containing the device component
        actuals = []
        for arg in  formals:
            name = arg["name"]
            actual = {}
            actual["name"] = name
            actual["param"] = name
            actuals.append(actual)
        devInst["actuals"] = actuals
        
        self.model["instances"] = { iName: devInst}     # Single instance (under iName)
        
        aModel = gModel["actors"][aName]
        self.model["locals"] = aModel["locals"]         # Locals
        self.model["internals"] = aModel["internals"]   # Internals 
        
        self.INT_RE = re.compile(r"^[-]?\d+$")
        self.parseParams(sysArgv)
        
        # Use czmq's context
        czmq_ctx = Zsys.init()
        self.context = zmq.Context.shadow(czmq_ctx.value)
        Zsys.handler_reset()  # Reset previous signal 
        
        # Context for app sockets
        self.appContext = zmq.Context()
        
        if Config.SECURITY:
            (self.public_key, self.private_key) = zmq.auth.load_certificate(const.appCertFile)
            _public = zmq.curve_public(self.private_key)
            if(self.public_key != _public):
                self.logger.error("bad security key(s)")
                raise BuildError("invalid security key(s)")
            hosts = ['127.0.0.1']
            try:
                with open(const.appDescFile, 'r') as f:
                    content = yaml.load(f, Loader=yaml.Loader)
                    hosts += content.hosts
            except:
                self.logger.error("Error loading app descriptor:s", str(sys.exc_info()[1]))

            self.auth = ThreadAuthenticator(self.appContext)
            self.auth.start()
            self.auth.allow(*hosts)
            self.auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY)
        else:
            (self.public_key, self.private_key) = (None, None)
            self.auth = None
            self.appContext = self.context
        
        try:
            if os.path.isfile(const.logConfFile) and os.access(const.logConfFile, os.R_OK):
                spdlog_setup.from_file(const.logConfFile)      
        except Exception as e:
            self.logger.error("error while configuring componentLogger: %s" % repr(e))  
        
        messages = gModel["messages"]  # Global message types (global on the network)
        self.messageNames = []
        for messageSpec in messages:
            self.messageNames.append(messageSpec["name"])
                   
        locals_ = self.model["locals"]  # Local message types (local to the host)
        self.localNames = []
        for messageSpec in locals_:
            self.localNames.append(messageSpec["type"]) 
            
        internals = self.model["internals"]  # Internal message types (internal to the actor process)
        self.internalNames = []
        for messageSpec in internals:
            self.internalNames.append(messageSpec["type"])
            
        groups = gModel["groups"]
        self.groupTypes = {} 
        for group in groups:
            self.groupTypes[group["name"]] = { 
                "kind": group["kind"],
                "message": group["message"],
                "timed": group["timed"]
            }
            
        self.components = {}
        instSpecs = self.model["instances"]
        _compSpecs = gModel["components"]
        devSpecs = gModel["devices"]
        for instName in instSpecs:  # Create the component instances: the 'parts'
            instSpec = instSpecs[instName]
            instType = instSpec['type']
            if instType in devSpecs: 
                typeSpec = devSpecs[instType]
            else:
                raise BuildError('Device type "%s" for instance "%s" is undefined' % (instType, instName))
            instFormals = typeSpec['formals']
            instActuals = instSpec['actuals']
            instArgs = self.buildInstArgs(instName, instFormals, instActuals)
            # Check whether the component is C++ component
            ccComponentFile = 'lib' + instType.lower() + '.so'
            ccComp = os.path.isfile(ccComponentFile)
            try:
                if ccComp:
                    modObj = importlib.import_module('lib' + instType.lower())
                    self.components[instName] = modObj.create_component_py(self, self.model,
                                                                           typeSpec, instName,
                                                                           instType, instArgs,
                                                                           self.appName, self.name, groups)
                else:
                    self.components[instName] = Part(self, typeSpec, instName, instType, instArgs)
            except Exception as e:
                traceback.print_exc()
                self.logger.error("Error while constructing part '%s.%s': %s" % (instType, instName, str(e)))
Beispiel #6
0
            "curve:// addresses must be in the form curve://HOST:PORT/REMOTE_PUBKEY_HEX",
            file=sys.stderr)
        sys.exit(1)
    sys.argv[1:0] = [pkhex]

if len(sys.argv) > 1 and len(sys.argv[1]) == 64 and all(
        x in "0123456789abcdefABCDEF" for x in sys.argv[1]):
    curve_pubkey = bytes.fromhex(sys.argv[1])
    del sys.argv[1]
    socket.curve_serverkey = curve_pubkey
    if len(sys.argv) > 1 and len(sys.argv[1]) == 64 and all(
            x in "0123456789abcdefABCDEF" for x in sys.argv[1]):
        my_privkey = bytes.fromhex(sys.argv[1])
        del sys.argv[1]
        my_pubkey = zmq.utils.z85.decode(
            zmq.curve_public(zmq.utils.z85.encode(my_privkey)))
    else:
        my_privkey = PrivateKey.generate()
        my_pubkey = my_privkey.public_key.encode()
        my_privkey = my_privkey.encode()

        print(
            "No curve client privkey given; generated a random one (pubkey: {}, privkey: {})"
            .format(my_pubkey.hex(), my_privkey.hex()),
            file=sys.stderr)
    socket.curve_secretkey = my_privkey
    socket.curve_publickey = my_pubkey

if not 2 <= len(sys.argv) <= 3 or any(x in y for x in ("--help", "-h")
                                      for y in sys.argv[1:]):
    print(
Beispiel #7
0
    def __init__(self, gModel, gModelName, aName, sysArgv):
        '''
        Constructor
        '''
        self.logger = logging.getLogger(__name__)
        self.inst_ = self
        self.appName = gModel["name"]
        self.modelName = gModelName
        self.name = aName
        self.pid = os.getpid()
        self.uuid = None
        self.setupIfaces()
        self.disco = None
        self.deplc = None
        # Assumption : pid is a 4 byte int
        self.actorID = ipaddress.IPv4Address(
            self.globalHost).packed + self.pid.to_bytes(4, 'big')
        self.suffix = ""
        if aName not in gModel["actors"]:
            raise BuildError('Actor "%s" unknown' % aName)
        self.model = gModel["actors"][
            aName]  # Fetch the relevant content from the model

        self.INT_RE = re.compile(r"^[-]?\d+$")
        self.parseParams(sysArgv)

        # Use czmq's context
        czmq_ctx = Zsys.init()
        self.context = zmq.Context.shadow(czmq_ctx.value)
        Zsys.handler_reset()  # Reset previous signal handler

        # Context for app sockets
        self.appContext = zmq.Context()

        if Config.SECURITY:
            (self.public_key,
             self.private_key) = zmq.auth.load_certificate(const.appCertFile)
            _public = zmq.curve_public(self.private_key)
            if (self.public_key != _public):
                self.logger.error("bad security key(s)")
                raise BuildError("invalid security key(s)")
            hosts = ['127.0.0.1']
            try:
                with open(const.appDescFile, 'r') as f:
                    content = yaml.load(f, Loader=yaml.Loader)
                    hosts += content.hosts
            except:
                self.logger.error("Error loading app descriptor:%s",
                                  str(sys.exc_info()[1]))

            self.auth = ThreadAuthenticator(self.appContext)
            self.auth.start()
            self.auth.allow(*hosts)
            self.auth.configure_curve(domain='*',
                                      location=zmq.auth.CURVE_ALLOW_ANY)
        else:
            (self.public_key, self.private_key) = (None, None)
            self.auth = None
            self.appContext = self.context

        try:
            if os.path.isfile(const.logConfFile) and os.access(
                    const.logConfFile, os.R_OK):
                spdlog_setup.from_file(const.logConfFile)
        except Exception as e:
            self.logger.error("error while configuring componentLogger: %s" %
                              repr(e))

        messages = gModel[
            "messages"]  # Global message types (global on the network)
        self.messageNames = []
        for messageSpec in messages:
            self.messageNames.append(messageSpec["name"])

        locals_ = self.model[
            "locals"]  # Local message types (local to the host)
        self.localNames = []
        for messageSpec in locals_:
            self.localNames.append(messageSpec["type"])
        self.localNams = set(self.localNames)

        internals = self.model[
            "internals"]  # Internal message types (internal to the actor process)
        self.internalNames = []
        for messageSpec in internals:
            self.internalNames.append(messageSpec["type"])
        self.internalNames = set(self.internalNames)

        groups = gModel["groups"]
        self.groupTypes = {}
        for group in groups:
            self.groupTypes[group["name"]] = {
                "kind": group["kind"],
                "message": group["message"],
                "timed": group["timed"]
            }

        self.rt_actor = self.model.get(
            "real-time")  # If real time actor, set scheduler (if specified)
        if self.rt_actor:
            sched = self.model.get("scheduler")
            if (sched):
                _policy = sched.get("policy")
                policy = {
                    "rr": os.SCHED_RR,
                    "pri": os.SCHED_FIFO
                }.get(_policy, None)
                priority = sched.get("priority", None)
                if policy and priority:
                    try:
                        param = os.sched_param(priority)
                        os.sched_setscheduler(0, policy, param)
                    except Exception as e:
                        self.logger.error(
                            "Can't set up real-time scheduling '%r %r':\n   %r"
                            % (_policy, priority, e))
            try:
                prctl.cap_effective.limit()  # Drop all capabilities
                prctl.cap_permitted.limit()
                prctl.cap_inheritable.limit()
            except Exception as e:
                self.logger.error("Error while dropping capabilities")
        self.components = {}
        instSpecs = self.model["instances"]
        compSpecs = gModel["components"]
        ioSpecs = gModel["devices"]
        for instName in instSpecs:  # Create the component instances: the 'parts'
            instSpec = instSpecs[instName]
            instType = instSpec['type']
            if instType in compSpecs:
                typeSpec = compSpecs[instType]
                ioComp = False
            elif instType in ioSpecs:
                typeSpec = ioSpecs[instType]
                ioComp = True
            else:
                raise BuildError(
                    'Component type "%s" for instance "%s" is undefined' %
                    (instType, instName))
            instFormals = typeSpec['formals']
            instActuals = instSpec['actuals']
            instArgs = self.buildInstArgs(instName, instFormals, instActuals)

            # Check whether the component is C++ component
            ccComponentFile = 'lib' + instType.lower() + '.so'
            ccComp = os.path.isfile(ccComponentFile)
            try:
                if not ioComp:
                    if ccComp:
                        modObj = importlib.import_module('lib' +
                                                         instType.lower())
                        self.components[instName] = modObj.create_component_py(
                            self, self.model, typeSpec, instName, instType,
                            instArgs, self.appName, self.name, groups)
                    else:
                        self.components[instName] = Part(
                            self, typeSpec, instName, instType, instArgs)
                else:
                    self.components[instName] = Peripheral(
                        self, typeSpec, instName, instType, instArgs)
            except Exception as e:
                traceback.print_exc()
                self.logger.error("Error while constructing part '%s.%s': %s" %
                                  (instType, instName, str(e)))