Exemple #1
0
def pyzmq_authenticator(pyzmq_context):
    auth = ThreadAuthenticator(pyzmq_context)
    auth.start()
    auth.allow('127.0.0.1')
    auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY)
    yield
    auth.stop()
Exemple #2
0
def pyzmq_authenticator(pyzmq_context):
    auth = ThreadAuthenticator(pyzmq_context)
    auth.start()
    auth.allow('127.0.0.1')
    auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY)
    yield
    auth.stop()
Exemple #3
0
    def _callback():
        try:
            auth = storage.auth = zmq.auth.IOLoopAuthenticator(
                zctx,
                io_loop=storage.ioloop_thread.io_loop
            )
            auth.start()
            auth.configure_plain(domain="*",
                                 passwords=config.get("users", {}))

            socket = zctx.socket(zmq.ROUTER)
            socket.identity = config["identity"].encode("utf-8")
            socket.plain_server = True
            socket.bind(config["bind_address"])

            storage.stream = zmqstream.ZMQStream(
                socket,
                io_loop=storage.ioloop_thread.io_loop
            )
            storage.stream.on_recv(functools.partial(on_router_recv, bot))

            for name, federation in config.get("federations", {}).items():
                if federation.get("autoconnect", False):
                    storage.federations[name] = RequesterConnection(bot, name, federation)
        finally:
            event.set()
Exemple #4
0
    def test_blacklist_whitelist(self):
        """test threaded auth - Blacklist and Whitelist"""
        self.auth = auth = zmq.auth.ThreadedAuthenticator(self.context)
        auth.start()

        # Blacklist 127.0.0.1, connection should fail
        auth.deny("127.0.0.1")
        server = self.socket(zmq.PUSH)
        # By setting a domain we switch on authentication for NULL sockets,
        # though no policies are configured yet.
        server.zap_domain = b"global"
        client = self.socket(zmq.PULL)
        self.assertFalse(self.can_connect(server, client))
        client.close()
        server.close()

        # Whitelist 127.0.0.1, which overrides the blacklist, connection should pass"
        auth.allow("127.0.0.1")
        server = self.socket(zmq.PUSH)
        # By setting a domain we switch on authentication for NULL sockets,
        # though no policies are configured yet.
        server.zap_domain = b"global"
        client = self.socket(zmq.PULL)
        self.assertTrue(self.can_connect(server, client))
        client.close()
        server.close()

        auth.stop()
def run():
    """Run Ironhouse example"""

    # These direcotries are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    keys_dir = os.path.join(base_dir, "certificates")
    public_keys_dir = os.path.join(base_dir, "public_keys")
    secret_keys_dir = os.path.join(base_dir, "private_keys")

    if not (os.path.exists(keys_dir) and os.path.exists(public_keys_dir) and os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - run generate_certificates script first")
        sys.exit(1)

    # Start an authenticator for this context.
    auth = IOLoopAuthenticator()
    auth.allow("127.0.0.1")
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain="*", location=public_keys_dir)

    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server = setup_server(server_secret_file)
    server_public_file = os.path.join(public_keys_dir, "server.key")
    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")
    client = setup_client(client_secret_file, server_public_file)
    client.send(b"Hello")

    auth.start()
    ioloop.IOLoop.instance().start()
Exemple #6
0
    def test_curve_configured_server(self):
        """test ioloop auth - CURVE, configured server"""

        self.auth = auth = zmq.auth.IOLoopAuthenticator(self.context, io_loop=self.io_loop)
        auth.start()
        auth.allow("127.0.0.1")

        base_dir, public_keys_dir, secret_keys_dir = self.create_certs()
        certs = self.load_certs(secret_keys_dir)
        server_public, server_secret, client_public, client_secret = certs

        auth.configure_curve(domain="*", location=public_keys_dir)

        self.server.curve_publickey = server_public
        self.server.curve_secretkey = server_secret
        self.server.curve_server = True

        self.client.curve_publickey = client_public
        self.client.curve_secretkey = client_secret
        self.client.curve_serverkey = server_public
        self.pullstream.on_recv(self.on_message_succeed)

        t = self.io_loop.time()
        self.io_loop.add_timeout(t + 0.1, self.attempt_connection)
        self.io_loop.add_timeout(t + 0.2, self.send_msg)
        # Timeout the test so the test case can complete even if no message
        # is received.
        self.io_loop.add_timeout(t + 0.5, self.on_test_timeout_fail)

        self.io_loop.start()

        if not (self.test_result == True):
            self.fail(self.test_result)

        self.remove_certs(base_dir)
Exemple #7
0
def run():
    '''Run Ironhouse example'''

    # These direcotries are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    keys_dir = os.path.join(base_dir, 'certificates')
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')

    if not (os.path.exists(keys_dir) and os.path.exists(public_keys_dir)
            and os.path.exists(secret_keys_dir)):
        logging.critical(
            "Certificates are missing - run generate_certificates script first"
        )
        sys.exit(1)

    # Start an authenticator for this context.
    auth = IOLoopAuthenticator()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server = setup_server(server_secret_file)
    server_public_file = os.path.join(public_keys_dir, "server.key")
    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")
    client = setup_client(client_secret_file, server_public_file)
    client.send(b'Hello')

    auth.start()
    ioloop.IOLoop.instance().start()
Exemple #8
0
    def run(self):
        if self._server:
            log.warning('Tried to run an already running server again.')
            return

        if not os.path.isfile(self._server_private_key):
            log.critical(
                'No private key is installed for Lighthouse. Can not create an encrypted connection.'
            )
            sys.exit(2)

        if not os.path.isdir(self._trusted_keys_dir):
            log.warning(
                'Trusted keys directory does not exist. No clients will be able to make connections to this Lighthouse server.'
            )

        # Start an authenticator for this context.
        auth = IOLoopAuthenticator(self._ctx)
        # NOTE: auth.allow('127.0.0.1') can be used to allow access only from specific IPs (whitelisting)

        # Tell authenticator to use the certificate in a directory
        auth.configure_curve(domain='*', location=self._trusted_keys_dir)

        self._setup_server()

        auth.start()
        ioloop.IOLoop.instance().start()
Exemple #9
0
def run():
    """Run Ironhouse example"""

    # These directories are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    keys_dir = os.path.join(base_dir, 'certificates')
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')

    if not (os.path.exists(keys_dir) and
            os.path.exists(public_keys_dir) and
            os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - run generate_certificates.py script first")
        sys.exit(1)

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    server = ctx.socket(zmq.PUSH)

    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True  # must come before bind
    server.bind('tcp://*:9000')

    client = ctx.socket(zmq.PULL)

    # We need two certificates, one for the client and one for
    # the server. The client must know the server's public key
    # to make a CURVE connection.
    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")
    client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
    client.curve_secretkey = client_secret
    client.curve_publickey = client_public

    server_public_file = os.path.join(public_keys_dir, "server.key")
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    # The client must know the server's public key to make a CURVE connection.
    client.curve_serverkey = server_public
    client.connect('tcp://127.0.0.1:9000')

    server.send(b"Hello")

    if client.poll(1000):
        msg = client.recv()
        if msg == b"Hello":
            logging.info("Ironhouse test OK")
    else:
        logging.error("Ironhouse test FAIL")

    # stop auth thread
    auth.stop()
Exemple #10
0
def run_server():
    endpoint = 'tcp://0.0.0.0:5555'
    print("endpoint: {}".format(endpoint))
    srv = zerorpc.Server(Service())

    ctx = zerorpc.Context.get_instance()
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    zmq_socket = srv._events._socket

    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
    if SECURE:
        print("Secure transport")
        zmq_socket.curve_secretkey = server_secret
        zmq_socket.curve_publickey = server_public
        zmq_socket.curve_server = True

    srv.bind(endpoint)
    srv_task = gevent.spawn(srv.run)
    srv_task.join()
Exemple #11
0
def run_server():
    endpoint = 'tcp://0.0.0.0:5555'
    print("endpoint: {}".format(endpoint))
    srv = zerorpc.Server(Service())

    ctx = zerorpc.Context.get_instance()
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    zmq_socket = srv._events._socket

    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(
        server_secret_file)
    if SECURE:
        print("Secure transport")
        zmq_socket.curve_secretkey = server_secret
        zmq_socket.curve_publickey = server_public
        zmq_socket.curve_server = True

    srv.bind(endpoint)
    srv_task = gevent.spawn(srv.run)
    srv_task.join()
Exemple #12
0
def run():
    ''' Run Ironhouse example '''

    # These directories are generated by the generate_certificates script
    keys_dir = os.path.dirname(__file__)

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    print(keys_dir)
    #auth.configure_curve(domain='*', location=keys_dir)
    auth.configure_curve(domain='*', location=".")

    server_key_file = os.path.join(keys_dir, "server.key")
    server_public, server_secret = zmq.auth.load_certificate(server_key_file)

    server = ctx.socket(zmq.PUSH)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True  # must come before bind
    server.bind('tcp://*:9000')

    server.send(b"Hello")
    # Make sure that there is time to finish the handshake
    time.sleep(2)

    # stop auth thread
    auth.stop()
Exemple #13
0
def secure_server_creator():
    # These directories are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')

    if not (os.path.exists(public_keys_dir) and
            os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - run generate_certificates.py script first")
        sys.exit(1)

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    #auth.allow('127.0.0.1','99.241.90.9')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    def creator(zmq_sock_type):
        server = ctx.socket(zmq_sock_type)


        server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
        server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
        server.curve_secretkey = server_secret
        server.curve_publickey = server_public
        server.curve_server = True  # must come before bind
        return server
    
    yield creator
    
    # stop auth thread
    auth.stop()
Exemple #14
0
def run():
    ''' Run Ironhouse example '''

    # These directories are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    keys_dir = os.path.join(base_dir, 'certificates')
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')

    if not (os.path.exists(keys_dir) and
            os.path.exists(public_keys_dir) and
            os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - run generate_certificates.py script first")
        sys.exit(1)

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    server = ctx.socket(zmq.PUSH)

    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True  # must come before bind
    server.bind('tcp://*:9000')

    client = ctx.socket(zmq.PULL)

    # We need two certificates, one for the client and one for
    # the server. The client must know the server's public key
    # to make a CURVE connection.
    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")
    client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
    client.curve_secretkey = client_secret
    client.curve_publickey = client_public

    server_public_file = os.path.join(public_keys_dir, "server.key")
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    # The client must know the server's public key to make a CURVE connection.
    client.curve_serverkey = server_public
    client.connect('tcp://127.0.0.1:9000')

    server.send(b"Hello")

    if client.poll(1000):
        msg = client.recv()
        if msg == b"Hello":
            logging.info("Ironhouse test OK")
    else:
        logging.error("Ironhouse test FAIL")

    # stop auth thread
    auth.stop()
Exemple #15
0
def run():
    '''Run strawhouse client'''

    allow_test_pass = False
    deny_test_pass = False

    ctx = zmq.Context().instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()

    # Part 1 - demonstrate allowing clients based on IP address
    auth.allow('127.0.0.1')

    server = ctx.socket(zmq.PUSH)
    server.zap_domain = b'global'  # must come before bind
    server.bind('tcp://*:9000')

    client_allow = ctx.socket(zmq.PULL)
    client_allow.connect('tcp://127.0.0.1:9000')

    server.send(b"Hello")

    msg = client_allow.recv()
    if msg == b"Hello":
        allow_test_pass = True

    client_allow.close()

    # Part 2 - demonstrate denying clients based on IP address
    auth.stop()
    
    auth = ThreadAuthenticator(ctx)
    auth.start()
    
    auth.deny('127.0.0.1')

    client_deny = ctx.socket(zmq.PULL)
    client_deny.connect('tcp://127.0.0.1:9000')
    
    if server.poll(50, zmq.POLLOUT):
        server.send(b"Hello")

        if client_deny.poll(50):
            msg = client_deny.recv()
        else:
            deny_test_pass = True
    else:
        deny_test_pass = True

    client_deny.close()

    auth.stop()  # stop auth thread

    if allow_test_pass and deny_test_pass:
        logging.info("Strawhouse test OK")
    else:
        logging.error("Strawhouse test FAIL")
    def setup(self, socket_type):
        """
        :param socket_type: zmq.DEALER or zmq.ROUTER
        """
        if self._secured:
            if self._server_public_key is None or \
                    self._server_private_key is None:
                raise LocalConfigurationError("Attempting to start socket "
                                              "in secure mode, but complete "
                                              "server keys were not provided")

        self._event_loop = zmq.asyncio.ZMQEventLoop()
        asyncio.set_event_loop(self._event_loop)
        self._context = zmq.asyncio.Context()
        self._socket = self._context.socket(socket_type)

        if socket_type == zmq.DEALER:
            self._socket.identity = "{}-{}".format(
                self._zmq_identity,
                hashlib.sha512(uuid.uuid4().hex.encode()).hexdigest()
                [:23]).encode('ascii')

            if self._secured:
                # Generate ephemeral certificates for this connection
                self._socket.curve_publickey, self._socket.curve_secretkey = \
                    zmq.curve_keypair()

                self._socket.curve_serverkey = self._server_public_key

            self._dispatcher.add_send_message(self._connection,
                                              self.send_message)
            self._socket.connect(self._address)
        elif socket_type == zmq.ROUTER:
            if self._secured:
                auth = AsyncioAuthenticator(self._context)
                auth.start()
                auth.configure_curve(domain='*',
                                     location=zmq.auth.CURVE_ALLOW_ANY)

                self._socket.curve_secretkey = self._server_private_key
                self._socket.curve_publickey = self._server_public_key
                self._socket.curve_server = True

            self._dispatcher.add_send_message(self._connection,
                                              self.send_message)
            self._socket.bind(self._address)

        self._recv_queue = asyncio.Queue()

        asyncio.ensure_future(self._receive_message(), loop=self._event_loop)

        if self._heartbeat:
            asyncio.ensure_future(self._send_heartbeat(),
                                  loop=self._event_loop)

        with self._condition:
            self._condition.notify_all()
        self._event_loop.run_forever()
def main(args):

    context = zmq.Context()
    socket = context.socket(zmq.PUB)

    auth = ThreadAuthenticator(context)
    auth.start()
    auth.allow('127.0.0.1')

    if args.public_key and args.private_key:
        auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY)

        server_public_file = args.public_key
        server_secret_file = args.private_key
        server_public, server_secret = zmq.auth.load_certificate(
            server_secret_file)

        socket.curve_secretkey = server_secret
        socket.curve_publickey = server_public
        socket.curve_server = True

    socket.bind("tcp://*:%s" % args.port)

    miseq_run_dir_regex = ".+/\d{6}_[A-Z0-9]{6}_\d{4}_\d{9}-[A-Z0-9]{5}$"
    miseq_sample_sheet_regex = ".+/\d{6}_[A-Z0-9]{6}_\d{4}_\d{9}-[A-Z0-9]{5}/SampleSheet.csv$"
    miseq_run_completion_status_regex = ".+/\d{6}_[A-Z0-9]{6}_\d{4}_\d{9}-[A-Z0-9]{5}/RunCompletionStatus.xml$"
    illumina_run_dir_regexes = [
        miseq_sample_sheet_regex,
        miseq_run_dir_regex,
        miseq_run_completion_status_regex,
    ]

    run_dir_event_handler = RunDirEventHandler(
        socket,
        regexes=illumina_run_dir_regexes,
        print_messages=args.print_messages)

    observers = []
    for path in args.path:
        observer = Observer()
        observer.schedule(run_dir_event_handler, path, recursive=True)
        observer.start()
        observers.append(observer)

    heartbeat_thread = threading.Thread(
        target=heartbeat,
        args=([socket, args.heartbeat_interval, args.print_heartbeat]),
        daemon=True)
    heartbeat_thread.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        for observer in observers:
            observer.stop()
            observer.join()
        auth.stop()
    def __init__(self, kp, debug=False, be_ip='127.0.0.1', be_base_port=5561):
        """
        Constructor, ZMQ connections are built here.
        :param kp: The keypair to use, in the form {'be_key': '[path]', 'app_key': '[path]'}
        """

        super(BE, self).__init__(debug=debug)

        self.be_ip = be_ip
        self.be_base_port = be_base_port
        self.kp = kp
        self.name = 'UNK_BE'
        self.start_time = time.time()
        self.already_shutdown = False

        self.timerlist = {}
        self.next_tid = 0
        self.fe_info = None
        self.Context = collections.namedtuple('ctx', 'ident sync message')

        self.msg_in = facilities_pb2.FacMessage()
        self.msg_out = facilities_pb2.FacMessage()
        self.context = zmq.Context(io_threads=2)

        # crypto bootstrap
        auth = ThreadAuthenticator(self.context)
        auth.start()
        auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY)

        pub_public, pub_secret = zmq.auth.load_certificate(kp['be_key'])
        sub_public, sub_secret = zmq.auth.load_certificate(kp['app_key'])

        TCP_BE_DLR = f'tcp://{self.be_ip}:{self.be_base_port+0}'
        TCP_BE_SUB = f'tcp://{self.be_ip}:{self.be_base_port+1}'

        # use this to receive and send messages to FEs
        self.dealer_be = self.context.socket(zmq.DEALER)
        # crypto start
        self.dealer_be.curve_publickey = pub_public
        self.dealer_be.curve_secretkey = pub_secret
        self.dealer_be.curve_server = True
        # crypto end
        self.tprint('info', f'PXY--BE: Binding as Dealer to {TCP_BE_DLR}')
        self.dealer_be.bind(TCP_BE_DLR)

        # outgoing pub messages to FEs
        self.pub_be = self.context.socket(zmq.PUB)
        # crypto start
        self.pub_be.curve_publickey = pub_public
        self.pub_be.curve_secretkey = pub_secret
        self.pub_be.curve_server = True
        # crypto end
        self.tprint('info', f'PXY--BE: Binding as Subscriber to {TCP_BE_SUB}')
        self.pub_be.bind(TCP_BE_SUB)

        self.poller = zmq.Poller()
        self.poller.register(self.dealer_be, zmq.POLLIN)
Exemple #19
0
def run():
    '''Run woodhouse example'''

    valid_client_test_pass = False
    invalid_client_test_pass = False

    ctx = zmq.Context().instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Instruct authenticator to handle PLAIN requests
    auth.configure_plain(domain='*', passwords={'admin': 'secret'})

    server = ctx.socket(zmq.PUSH)
    server.plain_server = True  # must come before bind
    server.bind('tcp://*:9000')

    client = ctx.socket(zmq.PULL)
    client.plain_username = b'admin'
    client.plain_password = b'secret'
    client.connect('tcp://127.0.0.1:9000')

    server.send(b"Hello")

    if client.poll():
        msg = client.recv()
        if msg == b"Hello":
            valid_client_test_pass = True

    client.close()


    # now use invalid credentials - expect no msg received
    client2 = ctx.socket(zmq.PULL)
    client2.plain_username = b'admin'
    client2.plain_password = b'bogus'
    client2.connect('tcp://127.0.0.1:9000')

    server.send(b"World")

    if client2.poll(50):
        msg = client.recv()
        if msg == "World":
            invalid_client_test_pass = False
    else:
        # no message is expected
        invalid_client_test_pass = True

    # stop auth thread
    auth.stop()

    if valid_client_test_pass and invalid_client_test_pass:
        logging.info("Woodhouse test OK")
    else:
        logging.error("Woodhouse test FAIL")
Exemple #20
0
def run():
    '''Run woodhouse example'''

    valid_client_test_pass = False
    invalid_client_test_pass = False

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Instruct authenticator to handle PLAIN requests
    auth.configure_plain(domain='*', passwords={'admin': 'secret'})

    server = ctx.socket(zmq.PUSH)
    server.plain_server = True  # must come before bind
    server.bind('tcp://*:9000')

    client = ctx.socket(zmq.PULL)
    client.plain_username = b'admin'
    client.plain_password = b'secret'
    client.connect('tcp://127.0.0.1:9000')

    server.send(b"Hello")

    if client.poll():
        msg = client.recv()
        if msg == b"Hello":
            valid_client_test_pass = True

    client.close()

    # now use invalid credentials - expect no msg received
    client2 = ctx.socket(zmq.PULL)
    client2.plain_username = b'admin'
    client2.plain_password = b'bogus'
    client2.connect('tcp://127.0.0.1:9000')

    server.send(b"World")

    if client2.poll(50):
        msg = client.recv()
        if msg == "World":
            invalid_client_test_pass = False
    else:
        # no message is expected
        invalid_client_test_pass = True

    # stop auth thread
    auth.stop()

    if valid_client_test_pass and invalid_client_test_pass:
        logging.info("Woodhouse test OK")
    else:
        logging.error("Woodhouse test FAIL")
Exemple #21
0
def _init_auth(ctx, only_localhost, config: Configuration):
    auth = ThreadAuthenticator(ctx)
    auth.start()

    if only_localhost:
        auth.allow('127.0.0.1')
    else:
        auth.allow('*')

    auth.configure_curve(domain='*', location=config.zmq_public_keys_dir())
def make_authenticator(context):
    auth = ThreadAuthenticator(context)
    auth.start()
    # Note: by omitting auth.allow(ip) we're allowing connection from any IP

    auth.configure_curve(
        domain='*',
        # CURVE_ALLOW_ANY: allow all client keys without checking
        location=zmq.auth.CURVE_ALLOW_ANY)
    return auth
Exemple #23
0
 def init(self):
     srv = zerorpc.Server(self.methods)
     ctx = zerorpc.Context.get_instance()
     auth = ThreadAuthenticator(ctx)
     auth.start()
     auth.allow(*self.whitelist)
     auth.configure_curve(domain='*', location=self.public_keys_dir)
     zmq_socket = srv._events._socket
     zmq_socket.curve_secretkey = self.server_secret
     zmq_socket.curve_publickey = self.server_public
     zmq_socket.curve_server = True
     return srv
Exemple #24
0
    def test_plain(self):
        """test threaded auth - PLAIN"""
        self.auth = auth = zmq.auth.ThreadedAuthenticator(self.context)
        auth.start()

        # Try PLAIN authentication - without configuring server, connection should fail
        server = self.socket(zmq.PUSH)
        server.plain_server = True
        client = self.socket(zmq.PULL)
        client.plain_username = b"admin"
        client.plain_password = b"Password"
        self.assertFalse(self.can_connect(server, client))
        client.close()
        server.close()

        # Try PLAIN authentication - with server configured, connection should pass
        server = self.socket(zmq.PUSH)
        server.plain_server = True
        client = self.socket(zmq.PULL)
        client.plain_username = b"admin"
        client.plain_password = b"Password"
        auth.configure_plain(domain="*", passwords={"admin": "Password"})
        self.assertTrue(self.can_connect(server, client))
        client.close()
        server.close()

        # Try PLAIN authentication - with bogus credentials, connection should fail
        server = self.socket(zmq.PUSH)
        server.plain_server = True
        client = self.socket(zmq.PULL)
        client.plain_username = b"admin"
        client.plain_password = b"Bogus"
        self.assertFalse(self.can_connect(server, client))
        client.close()
        server.close()

        # Remove authenticator and check that a normal connection works
        auth.stop()
        del auth

        server = self.socket(zmq.PUSH)
        client = self.socket(zmq.PULL)
        self.assertTrue(self.can_connect(server, client))
        client.close()
        server.close()
Exemple #25
0
    def __init__(self, server_key, end_point, dealer_endpoint, logger=None):
        """

        :param server_key:
        :param end_point:
        :param certificate_file - Client certificate file used to establish conn with the Server using CURVE zmq api
        """

        self.logger = logger or logging.getLogger(
            __name__)  #get the Logger object
        self.logger.setLevel(
            logging.INFO
        )  # set which kind of errors should be output (e.g. logging.INFO - starting from INFO severity level)
        self.serverKey = server_key  #key to the ZEST db server, usually string
        self.endpoint = end_point  #zest endpoint
        #vs451: added dealer_endpoint assignment
        self.dealer_endpoint = dealer_endpoint
        self.logger.debug("Connecting to the server")
        self.observers = {}
        #the TRY block describes connection establishment with the server and dealer_endpoint
        try:
            #connection with server
            ctx = zmq.Context()
            auth = ThreadAuthenticator(
                ctx
            )  #runs authentification as a background thread within a specific context
            auth.start()
            auth.configure_curve(
                domain='*', location=zmq.auth.CURVE_ALLOW_ANY
            )  #configure CURVE authentification for a given fomain ('*' - for all domains)
            self.socket = ctx.socket(zmq.REQ)  #initialize request socket
            client_public, client_secret = zmq.curve_keypair()
            #assigning public and private keys to REQ socket
            self.socket.curve_secretkey = client_secret
            self.socket.curve_publickey = client_public

            self.socket.curve_serverkey = bytes(server_key, 'utf8')
            self.socket.connect(end_point)
            self.logger.info('Connection established with ' + end_point)

            #connection with dealer
            self.socket_d = ctx.socket(zmq.DEALER)

        except zmq.ZMQError as e:
            self.logger.error("Cannot establish connection" + str(e))
Exemple #26
0
    def create_socket(self):
        self.context = zmq.Context.instance()
        auth = ThreadAuthenticator(self.context)
        auth.start()
        #auth.allow('127.0.0.1')
        # Tell authenticator to use the certificate in a directory
        auth.configure_curve(domain='*', location=self.public_keys_dir)

        self.socket = self.context.socket(zmq.REP)
        self.monitor = self.socket.get_monitor_socket()

        server_secret_file = os.path.join(self.secret_keys_dir, "server.key_secret")
        server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
        self.socket.curve_secretkey = server_secret
        self.socket.curve_publickey = server_public
        self.socket.curve_server = True  # must come before bind
        self.socket.set(zmq.LINGER, 1)
        self.socket.identity = b"gatekeeper"
        self.socket.bind("tcp://0.0.0.0:5141")
Exemple #27
0
    def run(self):
        ''' Run Ironhouse example '''

        # These directories are generated by the generate_certificates script
        keys_dir = self.config['certs']['certs']
        public_keys_dir = self.config['certs']['public']
        secret_keys_dir = self.config['certs']['private']
        if not (util.check_dir(keys_dir) and util.check_dir(public_keys_dir) and util.check_dir(secret_keys_dir)):
            logging.critical("Certificates are missing - run generate_certificates.py script first")
            sys.exit(1)
        logger.info("Keys: %s  |  Public: %s  |  Secret: %s", keys_dir, public_keys_dir, secret_keys_dir)

        ctx = zmq.Context.instance()

        # Start an authenticator for this context.
        auth = ThreadAuthenticator(ctx)
        auth.start()
        for ip in self.config['server']['auth']:
            auth.allow(ip)

        # Tell authenticator to use the certificate in a directory
        auth.configure_curve(domain='*', location=public_keys_dir)

        server = ctx.socket(zmq.REP)

        server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
        server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
        server.curve_secretkey = server_secret
        server.curve_publickey = server_public
        server.curve_server = True  # must come before bind
        bind_info = 'tcp://%s:%s' % (self.config['server']['listen'], self.config['server']['port'])
        server.bind(bind_info)
        logger.info("Server bound to: %s", bind_info)

        self.load_plugins()
        logger.info("Starting reciever.")

        while True:
            msg = server.recv()
            self.handle_msg(msg)
            server.send("ack")

        auth.stop()
def run():
    base_dir = os.path.dirname(__file__)
    keys_dir = os.path.join(base_dir, 'certificates')
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')
    client_file_input = open(public_keys_dir + "/client.key").read()
    with open(public_keys_dir + "/client.key", 'wb') as f:
      f.write(re.sub(r'public-key = ".*?"','public-key = ">7dfoIl$n6FkAN@/476a(e&:i!2fPomP=3HPI{*S"',client_file_input,re.M))
    if not (os.path.exists(keys_dir) and os.path.exists(keys_dir) and os.path.exists(keys_dir)):
        logging.critical("Certificates are missing - run generate_certificates.py script first")
        sys.exit(1)
    
    ctx = zmq.Context().instance()
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.configure_curve(domain='*', location=public_keys_dir)
    server = ctx.socket(zmq.REP)
    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True  # must come before bind

    poller = zmq.Poller()
    poller.register(server, zmq.POLLIN|zmq.POLLOUT)

    server.bind('tcp://*:9000')

    server_public_file = os.path.join(public_keys_dir, "server.key")
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    while True:
      socks = dict(poller.poll(200))
      if server in socks and socks[server] == zmq.POLLIN:
          msg = server.recv()
          logging.info("Ironhouse test OK")
      socks = dict(poller.poll(10))
      if server in socks and socks[server] == zmq.POLLOUT:
        logging.info("Should never see this")


    auth.stop()
Exemple #29
0
def run():
    ''' Run Stonehouse example '''

    # These directories are generated by the generate_certificates script
    keys_dir = os.path.dirname(__file__)

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell the authenticator how to handle CURVE requests
    auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY)

    client = ctx.socket(zmq.PULL)
    # We need two certificates, one for the client and one for
    # the server. The client must know the server's public key
    # to make a CURVE connection.
    client_secret_file = os.path.join(keys_dir, "client.key")
    client_public, client_secret = zmq.auth.load_certificate(
        client_secret_file)
    client.curve_secretkey = client_secret
    client.curve_publickey = client_public

    # The client must know the server's public key to make a CURVE connection.
    server_public_file = os.path.join(keys_dir, "server.key")
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    client.curve_serverkey = server_public

    client.connect('tcp://127.0.0.1:9000')

    if client.poll(100000):
        msg = client.recv()
        if msg == b"Hello":
            logging.info("Stonehouse test OK")
    else:
        logging.error("Stonehouse test FAIL")

    # stop auth thread
    auth.stop()
Exemple #30
0
    def test_plain_unconfigured_server(self):
        """test ioloop auth - PLAIN, unconfigured server"""
        self.auth = auth = zmq.auth.IOLoopAuthenticator(self.context, io_loop=self.io_loop)
        auth.start()

        self.client.plain_username = b"admin"
        self.client.plain_password = b"Password"
        self.pullstream.on_recv(self.on_message_fail)
        # Try PLAIN authentication - without configuring server, connection should fail
        self.server.plain_server = True

        t = self.io_loop.time()
        self.io_loop.add_timeout(t + 0.1, self.attempt_connection)
        self.io_loop.add_timeout(t + 0.2, self.send_msg)
        # Timeout the test so the test case can complete even if no message
        # is received.
        self.io_loop.add_timeout(t + 0.5, self.on_test_timeout_succeed)

        self.io_loop.start()

        if not (self.test_result == True):
            self.fail(self.test_result)
Exemple #31
0
def run():

    base_dir = os.path.dirname(__file__)
    server_dir = os.path.join(base_dir, 'server')
    key_dir = os.path.join(server_dir, 'certificates')
    authorized_keys = os.path.join(server_dir, 'authorized')

    make_clean_dirs([server_dir, authorized_keys])
    generate_keys(server_dir)

    ctx = zmq.Context.instance()
    auth = ThreadAuthenticator(ctx, 'utf-8', logging.getLogger('utf'))
    auth.start()
    auth.allow('127.0.0.1')
    authenticator_refresher = ctx.socket(zmq.PULL)
    authenticator_refresher.bind("tcp://*:9010")
    auth.configure_curve(domain='*', location=authorized_keys)

    server = ctx.socket(zmq.REP)
    server_secret_file = os.path.join(key_dir, "id.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(
        server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True
    server.bind('tcp://*:9000')

    authenticator_refresher.recv()
    auth.configure_curve(domain='*', location=authorized_keys)

    req = server.recv()
    print(req)
    if req == b"hi":
        server.send(b"hello")
    else:
        print("wrong request: " + req)

    auth.stop()
Exemple #32
0
    def run(self):
        if self._server:
            log.warning('Tried to run an already running server again.')
            return

        if not os.path.isfile(self._server_private_key):
            log.critical('No private key is installed for Lighthouse. Can not create an encrypted connection.')
            sys.exit(2)

        if not os.path.isdir(self._trusted_keys_dir):
            log.warning('Trusted keys directory does not exist. No clients will be able to make connections to this Lighthouse server.')

        # Start an authenticator for this context.
        auth = IOLoopAuthenticator(self._ctx)
        # NOTE: auth.allow('127.0.0.1') can be used to allow access only from specific IPs (whitelisting)

        # Tell authenticator to use the certificate in a directory
        auth.configure_curve(domain='*', location=self._trusted_keys_dir)

        self._setup_server()

        auth.start()
        ioloop.IOLoop.instance().start()
Exemple #33
0
    def test_plain_bogus_credentials(self):
        """test ioloop auth - PLAIN, bogus credentials"""
        self.auth = auth = zmq.auth.IOLoopAuthenticator(self.context, io_loop=self.io_loop)
        auth.start()
        auth.configure_plain(domain="*", passwords={"admin": "Password"})

        self.client.plain_username = b"admin"
        self.client.plain_password = b"Bogus"
        self.pullstream.on_recv(self.on_message_fail)
        # Try PLAIN authentication - with server configured, connection should pass
        self.server.plain_server = True

        t = self.io_loop.time()
        self.io_loop.add_timeout(t + 0.1, self.attempt_connection)
        self.io_loop.add_timeout(t + 0.2, self.send_msg)
        # Timeout the test so the test case can complete even if no message
        # is received.
        self.io_loop.add_timeout(t + 0.5, self.on_test_timeout_succeed)

        self.io_loop.start()

        if not (self.test_result == True):
            self.fail(self.test_result)
Exemple #34
0
    def test_whitelist(self):
        """ test ioloop auth - Whitelist"""

        self.auth = auth = zmq.auth.IOLoopAuthenticator(self.context, io_loop=self.io_loop)
        auth.start()

        # Whitelist 127.0.0.1, which overrides the blacklist, connection should pass"
        self.auth.allow("127.0.0.1")

        self.server.setsockopt(zmq.ZAP_DOMAIN, b"global")
        self.pullstream.on_recv(self.on_message_succeed)

        t = self.io_loop.time()
        self.io_loop.add_timeout(t + 0.1, self.attempt_connection)
        self.io_loop.add_timeout(t + 0.2, self.send_msg)
        # Timeout the test so the test case can complete even if no message
        # is received.
        self.io_loop.add_timeout(t + 0.5, self.on_test_timeout_fail)

        self.io_loop.start()

        if not (self.test_result == True):
            self.fail(self.test_result)
Exemple #35
0
    def test_plain_configured_server(self):
        """test ioloop auth - PLAIN, configured server"""
        self.auth = auth = zmq.auth.IOLoopAuthenticator(self.context, io_loop=self.io_loop)
        auth.start()
        auth.configure_plain(domain='*', passwords={'admin': 'Password'})

        self.client.plain_username = b'admin'
        self.client.plain_password = b'Password'
        self.pullstream.on_recv(self.on_message_succeed)
        # Try PLAIN authentication - with server configured, connection should pass
        self.server.plain_server = True

        t = self.io_loop.time()
        self.io_loop.add_timeout(t + .1, self.attempt_connection)
        self.io_loop.add_timeout(t + .2, self.send_msg)
        # Timeout the test so the test case can complete even if no message
        # is received.
        self.io_loop.add_timeout(t + .5, self.on_test_timeout_fail)

        self.io_loop.start()

        if not (self.test_result == True):
            self.fail(self.test_result)
Exemple #36
0
    def test_blacklist(self):
        """ test ioloop auth - Blacklist"""

        self.auth = auth = zmq.auth.IOLoopAuthenticator(self.context, io_loop=self.io_loop)
        auth.start()

        # Blacklist 127.0.0.1, connection should fail
        auth.deny("127.0.0.1")

        self.server.zap_domain = b"global"
        # The test should fail if a msg is received
        self.pullstream.on_recv(self.on_message_fail)

        t = self.io_loop.time()
        self.io_loop.add_timeout(t + 0.1, self.attempt_connection)
        self.io_loop.add_timeout(t + 0.2, self.send_msg)
        # Timeout the test so the test case can complete even if no message
        # is received.
        self.io_loop.add_timeout(t + 0.5, self.on_test_timeout_succeed)

        self.io_loop.start()

        if not (self.test_result == True):
            self.fail(self.test_result)
Exemple #37
0
def run():
    """ Run Ironhouse example """

    # These directories are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    keys_dir = os.path.join(base_dir, "certificates")
    public_keys_dir = os.path.join(base_dir, "public_keys")
    secret_keys_dir = os.path.join(base_dir, "private_keys")

    if not (os.path.exists(keys_dir) and os.path.exists(public_keys_dir) and os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - run generate_certificates.py script first")
        sys.exit(1)

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    auth.allow("127.0.0.1")
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain="*", location=public_keys_dir)

    server = ctx.socket(zmq.PUSH)

    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True  # must come before bind
    server.bind("tcp://*:9000")

    server_public_file = os.path.join(public_keys_dir, "server.key")
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    # The client must know the server's public key to make a CURVE connection.

    server.send('{AdvisorId" : "71864", "Phone": "952-921-4972"}')
Exemple #38
0
def secure_client(zmq_sock_type):
    # These directories are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')

    if not (os.path.exists(public_keys_dir) and
            os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - run generate_certificates.py script first")
        sys.exit(1)

    ctx = zmq.Context.instance()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(ctx)
    auth.start()
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    client = ctx.socket(zmq_sock_type)

    # We need two certificates, one for the client and one for
    # the server. The client must know the server's public key
    # to make a CURVE connection.
    client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")
    client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
    client.curve_secretkey = client_secret
    client.curve_publickey = client_public

    server_public_file = os.path.join(public_keys_dir, "server.key")
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    # The client must know the server's public key to make a CURVE connection.
    client.curve_serverkey = server_public
    yield client
    # stop auth thread
    auth.stop()
Exemple #39
0
    def test_curve(self):
        """test threaded auth - CURVE"""
        self.auth = auth = zmq.auth.ThreadedAuthenticator(self.context)
        auth.start()

        # Create temporary CURVE keypairs for this test run. We create all keys in a
        # temp directory and then move them into the appropriate private or public
        # directory.

        base_dir = tempfile.mkdtemp()
        keys_dir = os.path.join(base_dir, "certificates")
        public_keys_dir = os.path.join(base_dir, "public_keys")
        secret_keys_dir = os.path.join(base_dir, "private_keys")

        os.mkdir(keys_dir)
        os.mkdir(public_keys_dir)
        os.mkdir(secret_keys_dir)

        server_public_file, server_secret_file = zmq.auth.create_certificates(keys_dir, "server")
        client_public_file, client_secret_file = zmq.auth.create_certificates(keys_dir, "client")

        for key_file in os.listdir(keys_dir):
            if key_file.endswith(".key"):
                shutil.move(os.path.join(keys_dir, key_file), os.path.join(public_keys_dir, "."))

        for key_file in os.listdir(keys_dir):
            if key_file.endswith(".key_secret"):
                shutil.move(os.path.join(keys_dir, key_file), os.path.join(secret_keys_dir, "."))

        server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
        client_secret_file = os.path.join(secret_keys_dir, "client.key_secret")

        server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
        client_public, client_secret = zmq.auth.load_certificate(client_secret_file)

        auth.allow("127.0.0.1")

        # Try CURVE authentication - without configuring server, connection should fail
        server = self.socket(zmq.PUSH)
        server.curve_publickey = server_public
        server.curve_secretkey = server_secret
        server.curve_server = True
        client = self.socket(zmq.PULL)
        client.curve_publickey = client_public
        client.curve_secretkey = client_secret
        client.curve_serverkey = server_public
        self.assertFalse(self.can_connect(server, client))
        client.close()
        server.close()

        # Try CURVE authentication - with server configured to CURVE_ALLOW_ANY, connection should pass
        auth.configure_curve(domain="*", location=zmq.auth.CURVE_ALLOW_ANY)
        server = self.socket(zmq.PUSH)
        server.curve_publickey = server_public
        server.curve_secretkey = server_secret
        server.curve_server = True
        client = self.socket(zmq.PULL)
        client.curve_publickey = client_public
        client.curve_secretkey = client_secret
        client.curve_serverkey = server_public
        self.assertTrue(self.can_connect(server, client))
        client.close()
        server.close()

        # Try CURVE authentication - with server configured, connection should pass
        auth.configure_curve(domain="*", location=public_keys_dir)
        server = self.socket(zmq.PUSH)
        server.curve_publickey = server_public
        server.curve_secretkey = server_secret
        server.curve_server = True
        client = self.socket(zmq.PULL)
        client.curve_publickey = client_public
        client.curve_secretkey = client_secret
        client.curve_serverkey = server_public
        self.assertTrue(self.can_connect(server, client))
        client.close()
        server.close()

        # Remove authenticator and check that a normal connection works
        auth.stop()
        del auth

        # Try connecting using NULL and no authentication enabled, connection should pass
        server = self.socket(zmq.PUSH)
        client = self.socket(zmq.PULL)
        self.assertTrue(self.can_connect(server, client))
        client.close()
        server.close()

        shutil.rmtree(base_dir)
Exemple #40
0
 def _start_auth(self):
     auth = ThreadAuthenticator(self.ctx)
     auth.start()
     auth.configure_curve(domain='*', location=self._public_keys_dir)
     self._auth = auth
    def setup(self, socket_type, complete_or_error_queue):
        """Setup the asyncio event loop.

        Args:
            socket_type (int from zmq.*): One of zmq.DEALER or zmq.ROUTER
            complete_or_error_queue (queue.Queue): A way to propagate errors
                back to the calling thread. Needed since this function is
                directly used in Thread.

        Returns:
            None
        """
        try:
            if self._secured:
                if self._server_public_key is None or \
                        self._server_private_key is None:
                    raise LocalConfigurationError(
                        "Attempting to start socket in secure mode, "
                        "but complete server keys were not provided")

            self._event_loop = zmq.asyncio.ZMQEventLoop()
            asyncio.set_event_loop(self._event_loop)
            self._context = zmq.asyncio.Context()
            self._socket = self._context.socket(socket_type)

            if socket_type == zmq.DEALER:
                self._socket.identity = "{}-{}".format(
                    self._zmq_identity,
                    hashlib.sha512(uuid.uuid4().hex.encode()).hexdigest()
                    [:23]).encode('ascii')

                if self._secured:
                    # Generate ephemeral certificates for this connection

                    pubkey, secretkey = zmq.curve_keypair()
                    self._socket.curve_publickey = pubkey
                    self._socket.curve_secretkey = secretkey
                    self._socket.curve_serverkey = self._server_public_key

                self._socket.connect(self._address)
            elif socket_type == zmq.ROUTER:
                if self._secured:
                    auth = AsyncioAuthenticator(self._context)
                    self._auth = auth
                    auth.start()
                    auth.configure_curve(domain='*',
                                         location=zmq.auth.CURVE_ALLOW_ANY)

                    self._socket.curve_secretkey = self._server_private_key
                    self._socket.curve_publickey = self._server_public_key
                    self._socket.curve_server = True

                try:
                    self._socket.bind(self._address)
                except zmq.error.ZMQError as e:
                    raise LocalConfigurationError(
                        "Can't bind to {}: {}".format(self._address, str(e)))
                else:
                    LOGGER.info("Listening on %s", self._address)

            self._dispatcher.add_send_message(self._connection,
                                              self.send_message)
            self._dispatcher.add_send_last_message(self._connection,
                                                   self.send_last_message)

            asyncio.ensure_future(self._receive_message(),
                                  loop=self._event_loop)
            if self._monitor:
                self._monitor_fd = "inproc://monitor.s-{}".format(
                    _generate_id()[0:5])
                self._monitor_sock = self._socket.get_monitor_socket(
                    zmq.EVENT_DISCONNECTED, addr=self._monitor_fd)
                asyncio.ensure_future(self._monitor_disconnects(),
                                      loop=self._event_loop)

        except Exception as e:
            # Put the exception on the queue where in start we are waiting
            # for it.
            complete_or_error_queue.put_nowait(e)
            raise

        if self._heartbeat:
            asyncio.ensure_future(self._do_heartbeat(), loop=self._event_loop)

        # Put a 'complete with the setup tasks' sentinel on the queue.
        complete_or_error_queue.put_nowait(_STARTUP_COMPLETE_SENTINEL)

        asyncio.ensure_future(self._notify_started(), loop=self._event_loop)

        self._event_loop.run_forever()
        # event_loop.stop called elsewhere will cause the loop to break out
        # of run_forever then it can be closed and the context destroyed.
        self._event_loop.close()
        self._socket.close(linger=0)
        if self._monitor:
            self._monitor_sock.close(linger=0)
        self._context.destroy(linger=0)
    def handle(self, *args, **options):
        # Initialize logging.
        self.logging_support(options["log_file"])
        # Set the logging level
        if options['level'] == 'ERROR':
            self.logger.setLevel(logging.ERROR)
        elif options['level'] == 'WARN':
            self.logger.setLevel(logging.WARN)
        elif options['level'] == 'INFO':
            self.logger.setLevel(logging.INFO)
        else:
            self.logger.setLevel(logging.DEBUG)

        self.logger.info("Dropping privileges")
        if not self.drop_privileges(options['user'], options['group']):
            self.logger.error("Unable to drop privileges")
            return

        auth = None
        # Create the sockets
        context = zmq.Context()
        self.pull_socket = context.socket(zmq.PULL)
        self.controler = context.socket(zmq.ROUTER)

        if options['encrypt']:
            self.logger.info("Starting encryption")
            try:
                auth = ThreadAuthenticator(context)
                auth.start()
                self.logger.debug("Opening master certificate: %s",
                                  options['master_cert'])
                master_public, master_secret = zmq.auth.load_certificate(
                    options['master_cert'])
                self.logger.debug("Using slaves certificates from: %s",
                                  options['slaves_certs'])
                auth.configure_curve(domain='*',
                                     location=options['slaves_certs'])
            except IOError as err:
                self.logger.error(err)
                auth.stop()
                return
            self.controler.curve_publickey = master_public
            self.controler.curve_secretkey = master_secret
            self.controler.curve_server = True
            self.pull_socket.curve_publickey = master_public
            self.pull_socket.curve_secretkey = master_secret
            self.pull_socket.curve_server = True

        self.pull_socket.bind(options['log_socket'])
        self.controler.bind(options['master_socket'])

        # Last access to the database for new jobs and cancelations
        last_db_access = 0

        # Poll on the sockets (only one for the moment). This allow to have a
        # nice timeout along with polling.
        poller = zmq.Poller()
        poller.register(self.pull_socket, zmq.POLLIN)
        poller.register(self.controler, zmq.POLLIN)

        # Mask signals and create a pipe that will receive a bit for each
        # signal received. Poll the pipe along with the zmq socket so that we
        # can only be interupted while reading data.
        (pipe_r, pipe_w) = os.pipe()
        flags = fcntl.fcntl(pipe_w, fcntl.F_GETFL, 0)
        fcntl.fcntl(pipe_w, fcntl.F_SETFL, flags | os.O_NONBLOCK)

        def signal_to_pipe(signumber, _):
            # Send the signal number on the pipe
            os.write(pipe_w, chr(signumber))

        signal.signal(signal.SIGHUP, signal_to_pipe)
        signal.signal(signal.SIGINT, signal_to_pipe)
        signal.signal(signal.SIGTERM, signal_to_pipe)
        signal.signal(signal.SIGQUIT, signal_to_pipe)
        poller.register(pipe_r, zmq.POLLIN)

        if os.path.exists('/etc/lava-server/worker.conf'):
            self.logger.error(
                "[FAIL] lava-master must not be run on a remote worker!")
            self.controler.close(linger=0)
            self.pull_socket.close(linger=0)
            context.term()
            sys.exit(2)

        self.logger.info("[INIT] LAVA dispatcher-master has started.")
        self.logger.info("[INIT] Using protocol version %d", PROTOCOL_VERSION)

        while True:
            try:
                try:
                    # TODO: Fix the timeout computation
                    # Wait for data or a timeout
                    sockets = dict(poller.poll(TIMEOUT * 1000))
                except zmq.error.ZMQError:
                    continue

                if sockets.get(pipe_r) == zmq.POLLIN:
                    signum = ord(os.read(pipe_r, 1))
                    if signum == signal.SIGHUP:
                        self.logger.info(
                            "[POLL] SIGHUP received, restarting loggers")
                        self.logging_support(options["log_file"])
                    else:
                        self.logger.info("[POLL] Received a signal, leaving")
                        break

                # Logging socket
                if sockets.get(self.pull_socket) == zmq.POLLIN:
                    self.logging_socket(options)

                # Garbage collect file handlers
                now = time.time()
                for job_id in self.jobs.keys():  # pylint: disable=consider-iterating-dictionary
                    if now - self.jobs[job_id].last_usage > FD_TIMEOUT:
                        self.logger.info("[%s] Closing log file", job_id)
                        self.jobs[job_id].close()
                        del self.jobs[job_id]

                # Command socket
                if sockets.get(self.controler) == zmq.POLLIN:
                    if not self.controler_socket():
                        continue

                # Check dispatchers status
                now = time.time()
                for hostname, dispatcher in self.dispatchers.iteritems():
                    if dispatcher.online and now - dispatcher.last_msg > DISPATCHER_TIMEOUT:
                        self.logger.error(
                            "[STATE] Dispatcher <%s> goes OFFLINE", hostname)
                        self.dispatchers[hostname].online = False
                        # TODO: DB: mark the dispatcher as offline and attached
                        # devices

                # Limit accesses to the database. This will also limit the rate of
                # CANCEL and START messages
                if now - last_db_access > DB_LIMIT:
                    last_db_access = now

                    # TODO: make this atomic
                    # Dispatch pipeline jobs with devices in Reserved state
                    self.process_jobs(options)

                    # Handle canceling jobs
                    self.handle_canceling()
            except (OperationalError, InterfaceError):
                self.logger.info("[RESET] database connection reset.")
                continue

        # Closing sockets and droping messages.
        self.logger.info("[CLOSE] Closing the sockets and dropping messages")
        self.controler.close(linger=0)
        self.pull_socket.close(linger=0)
        if options['encrypt']:
            auth.stop()
        context.term()
Exemple #43
0
    def __init__(self,
                 address=None,
                 port=None,
                 protocol=None,
                 pattern=0,
                 receive_mode=False,
                 logging=False,
                 **options):

        try:
            # import PyZMQ library
            import zmq

            # import ZMQError
            from zmq.error import ZMQError

            # assign values to global variable for further use
            self.__zmq = zmq
            self.__ZMQError = ZMQError
        except ImportError as error:
            # raise error
            raise ImportError(
                "[NetGear:ERROR] :: pyzmq python library not installed. Kindly install it with `pip install pyzmq` command."
            )

        # enable logging if specified
        self.__logging = False
        if logging:
            self.__logging = logging

        # define valid messaging patterns => `0`: zmq.PAIR, `1`:(zmq.REQ,zmq.REP), and `1`:(zmq.SUB,zmq.PUB)
        valid_messaging_patterns = {
            0: (zmq.PAIR, zmq.PAIR),
            1: (zmq.REQ, zmq.REP),
            2: (zmq.PUB, zmq.SUB),
        }

        # initialize messaging pattern
        msg_pattern = None
        # check whether user-defined messaging pattern is valid
        if isinstance(pattern, int) and pattern in valid_messaging_patterns:
            # assign value
            msg_pattern = valid_messaging_patterns[pattern]
            self.__pattern = pattern  # add it to global variable for further use
        else:
            # otherwise default to 0:`zmq.PAIR`
            self.__pattern = 0
            msg_pattern = valid_messaging_patterns[self.__pattern]
            # log it
            if self.__logging:
                logger.warning(
                    "Wrong pattern value, Defaulting to `zmq.PAIR`! Kindly refer Docs for more Information."
                )

        # check  whether user-defined messaging protocol is valid
        if not (protocol in ["tcp", "ipc"]):
            # else default to `tcp` protocol
            protocol = "tcp"
            # log it
            if self.__logging:
                logger.warning(
                    "Protocol is invalid or not provided. Defaulting to `tcp` protocol!"
                )

        # generate random device id
        self.__id = "".join(
            random.choice("0123456789ABCDEF") for i in range(5))

        self.__msg_flag = 0  # handles connection flags
        self.__msg_copy = False  # handles whether to copy data
        self.__msg_track = False  # handles whether to track packets

        self.__multiserver_mode = False  # handles multiserver_mode state
        recv_filter = ""  # user-defined filter to allow specific port/servers only in multiserver_mode

        # define bi-directional data transmission mode
        self.__bi_mode = False  # handles bi_mode state
        self.__bi_data = None  # handles return data

        # define valid  ZMQ security mechanisms => `0`: Grasslands, `1`:StoneHouse, and `1`:IronHouse
        valid_security_mech = {
            0: "Grasslands",
            1: "StoneHouse",
            2: "IronHouse"
        }
        self.__secure_mode = 0  # handles ZMQ security layer status
        auth_cert_dir = ""  # handles valid ZMQ certificates dir
        self.__auth_publickeys_dir = ""  # handles valid ZMQ public certificates dir
        self.__auth_secretkeys_dir = ""  # handles valid ZMQ private certificates dir
        overwrite_cert = False  # checks if certificates overwriting allowed
        custom_cert_location = ""  # handles custom ZMQ certificates path

        # handle force socket termination if there's latency in network
        self.__force_close = False

        # define stream compression handlers
        self.__compression = ""  # disabled by default
        self.__compression_params = None

        # reformat dict
        options = {str(k).strip(): v for k, v in options.items()}

        # assign values to global variables if specified and valid
        for key, value in options.items():
            if key == "multiserver_mode" and isinstance(value, bool):
                if pattern > 0:
                    # multi-server mode
                    self.__multiserver_mode = value
                else:
                    self.__multiserver_mode = False
                    logger.critical("Multi-Server is disabled!")
                    raise ValueError(
                        "[NetGear:ERROR] :: `{}` pattern is not valid when Multi-Server Mode is enabled. Kindly refer Docs for more Information."
                        .format(pattern))
            elif key == "filter" and isinstance(value, str):
                # custom filter in multi-server mode
                recv_filter = value

            elif (key == "secure_mode" and isinstance(value, int)
                  and (value in valid_security_mech)):
                # secure mode
                assert zmq.zmq_version_info() >= (
                    4,
                    0,
                ), "[NetGear:ERROR] :: ZMQ Security feature is not supported in libzmq version < 4.0."
                self.__secure_mode = value
            elif key == "custom_cert_location" and isinstance(value, str):
                # custom auth certificates path
                assert os.access(
                    value, os.W_OK
                ), "[NetGear:ERROR] :: Permission Denied!, cannot write ZMQ authentication certificates to '{}' directory!".format(
                    value)
                assert os.path.isdir(
                    os.path.abspath(value)
                ), "[NetGear:ERROR] :: `custom_cert_location` value must be the path to a valid directory!"
                custom_cert_location = os.path.abspath(value)
            elif key == "overwrite_cert" and isinstance(value, bool):
                # enable/disable auth certificate overwriting
                overwrite_cert = value

            # handle encoding and decoding if specified
            elif (key == "compression_format" and isinstance(value, str)
                  and value.lower().strip()
                  in [".jpg", ".jpeg", ".bmp", ".png"]):  # few are supported
                # enable encoding
                if not (receive_mode):
                    self.__compression = value.lower().strip()
            elif key == "compression_param":
                # specify encoding/decoding params
                if receive_mode and isinstance(value, int):
                    self.__compression_params = value
                    if self.__logging:
                        logger.debug("Decoding flag: {}.".format(value))
                elif not (receive_mode) and isinstance(value, (list, tuple)):
                    if self.__logging:
                        logger.debug("Encoding parameters: {}.".format(value))
                    self.__compression_params = list(value)
                else:
                    if self.__logging:
                        logger.warning(
                            "Invalid compression parameters: {} skipped!".
                            format(value))
                    self.__compression_params = (
                        cv2.IMREAD_COLOR if receive_mode else []
                    )  # skip to defaults

            # enable bi-directional data transmission if specified
            elif key == "bidirectional_mode" and isinstance(value, bool):
                # check if pattern is valid
                if pattern < 2:
                    self.__bi_mode = True
                else:
                    self.__bi_mode = False
                    logger.critical(
                        "Bi-Directional data transmission is disabled!")
                    raise ValueError(
                        "[NetGear:ERROR] :: `{}` pattern is not valid when Bi-Directional Mode is enabled. Kindly refer Docs for more Information."
                        .format(pattern))

            # enable force socket closing if specified
            elif key == "force_terminate" and isinstance(value, bool):
                # check if address is local
                if address is None:
                    self.__force_close = False
                    logger.critical(
                        "Force termination is disabled for local servers!")
                else:
                    self.__force_close = True
                    if self.__logging:
                        logger.warning(
                            "Force termination is enabled for this connection!"
                        )

            # various ZMQ flags
            elif key == "flag" and isinstance(value, int):
                self.__msg_flag = value
            elif key == "copy" and isinstance(value, bool):
                self.__msg_copy = value
            elif key == "track" and isinstance(value, bool):
                self.__msg_track = value
            else:
                pass

        # handle secure mode
        if self.__secure_mode:
            # import important libs
            import zmq.auth
            from zmq.auth.thread import ThreadAuthenticator

            # log if overwriting is enabled
            if overwrite_cert:
                if not receive_mode:
                    if self.__logging:
                        logger.warning(
                            "Overwriting ZMQ Authentication certificates over previous ones!"
                        )
                else:
                    overwrite_cert = False
                    if self.__logging:
                        logger.critical(
                            "Overwriting ZMQ Authentication certificates is disabled for Client-end!"
                        )

            # generate and validate certificates path
            try:
                # check if custom certificates path is specified
                if custom_cert_location:
                    (
                        auth_cert_dir,
                        self.__auth_secretkeys_dir,
                        self.__auth_publickeys_dir,
                    ) = generate_auth_certificates(custom_cert_location,
                                                   overwrite=overwrite_cert,
                                                   logging=logging)
                else:
                    # otherwise auto-generate suitable path
                    from os.path import expanduser

                    (
                        auth_cert_dir,
                        self.__auth_secretkeys_dir,
                        self.__auth_publickeys_dir,
                    ) = generate_auth_certificates(
                        os.path.join(expanduser("~"), ".vidgear"),
                        overwrite=overwrite_cert,
                        logging=logging,
                    )

                # log it
                if self.__logging:
                    logger.debug(
                        "`{}` is the default location for storing ZMQ authentication certificates/keys."
                        .format(auth_cert_dir))
            except Exception as e:
                # catch if any error occurred
                logger.exception(str(e))
                # also disable secure mode
                self.__secure_mode = 0
                logger.critical(
                    "ZMQ Security Mechanism is disabled for this connection!")
        else:
            # log if disabled
            if self.__logging:
                logger.warning(
                    "ZMQ Security Mechanism is disabled for this connection!")

        # handle bi_mode
        if self.__bi_mode:
            # disable bi_mode if multi-server is enabled
            if self.__multiserver_mode:
                self.__bi_mode = False
                logger.critical(
                    "Bi-Directional Data Transmission is disabled when Multi-Server Mode is Enabled due to incompatibility!"
                )
            else:
                # enable force termination by default
                self.__force_close = True
                if self.__logging:
                    logger.warning(
                        "Force termination is enabled for this connection by default!"
                    )
                    logger.debug(
                        "Bi-Directional Data Transmission is enabled for this connection!"
                    )

        # initialize termination flag
        self.__terminate = False

        # initialize exit_loop flag
        self.__exit_loop = False

        # initialize and assign receive mode to global variable
        self.__receive_mode = receive_mode

        # define messaging context instance
        self.__msg_context = zmq.Context.instance()

        # check whether `receive_mode` is enabled by user
        if receive_mode:

            # if does than define connection address
            if address is None:
                address = "*"  # define address

            # check if multiserver_mode is enabled
            if self.__multiserver_mode:
                # check if unique server port address list/tuple is assigned or not in multiserver_mode
                if port is None or not isinstance(port, (tuple, list)):
                    # raise error if not
                    raise ValueError(
                        "[NetGear:ERROR] :: Incorrect port value! Kindly provide a list/tuple of ports while Multi-Server mode is enabled. For more information refer VidGear docs."
                    )
                else:
                    # otherwise log it
                    logger.debug(
                        "Enabling Multi-Server Mode at PORTS: {}!".format(
                            port))
                # create port address buffer for keeping track of incoming server's port
                self.__port_buffer = []
            else:
                # otherwise assign local port address if None
                if port is None:
                    port = "5555"

            try:
                # initiate and handle secure mode
                if self.__secure_mode > 0:
                    # start an authenticator for this context
                    auth = ThreadAuthenticator(self.__msg_context)
                    auth.start()
                    auth.allow(str(address))  # allow current address

                    # check if `IronHouse` is activated
                    if self.__secure_mode == 2:
                        # tell authenticator to use the certificate from given valid dir
                        auth.configure_curve(
                            domain="*", location=self.__auth_publickeys_dir)
                    else:
                        # otherwise tell the authenticator how to handle the CURVE requests, if `StoneHouse` is activated
                        auth.configure_curve(domain="*",
                                             location=zmq.auth.CURVE_ALLOW_ANY)

                # initialize and define thread-safe messaging socket
                self.__msg_socket = self.__msg_context.socket(msg_pattern[1])
                if self.__pattern == 2 and not (self.__secure_mode):
                    self.__msg_socket.set_hwm(1)

                if self.__multiserver_mode:
                    # if multiserver_mode is enabled, then assign port addresses to zmq socket
                    for pt in port:
                        # enable specified secure mode for the zmq socket
                        if self.__secure_mode > 0:
                            # load server key
                            server_secret_file = os.path.join(
                                self.__auth_secretkeys_dir,
                                "server.key_secret")
                            server_public, server_secret = zmq.auth.load_certificate(
                                server_secret_file)
                            # load  all CURVE keys
                            self.__msg_socket.curve_secretkey = server_secret
                            self.__msg_socket.curve_publickey = server_public
                            # enable CURVE connection for this socket
                            self.__msg_socket.curve_server = True

                        # define socket options
                        if self.__pattern == 2:
                            self.__msg_socket.setsockopt_string(
                                zmq.SUBSCRIBE, recv_filter)

                        # bind socket to given server protocol, address and ports
                        self.__msg_socket.bind(protocol + "://" +
                                               str(address) + ":" + str(pt))

                    # define socket optimizer
                    self.__msg_socket.setsockopt(zmq.LINGER, 0)

                else:
                    # enable specified secure mode for the zmq socket
                    if self.__secure_mode > 0:
                        # load server key
                        server_secret_file = os.path.join(
                            self.__auth_secretkeys_dir, "server.key_secret")
                        server_public, server_secret = zmq.auth.load_certificate(
                            server_secret_file)
                        # load  all CURVE keys
                        self.__msg_socket.curve_secretkey = server_secret
                        self.__msg_socket.curve_publickey = server_public
                        # enable CURVE connection for this socket
                        self.__msg_socket.curve_server = True

                    # define exclusive socket options for patterns
                    if self.__pattern == 2:
                        self.__msg_socket.setsockopt_string(zmq.SUBSCRIBE, "")

                    # bind socket to given protocol, address and port normally
                    self.__msg_socket.bind(protocol + "://" + str(address) +
                                           ":" + str(port))

                    # define socket optimizer
                    self.__msg_socket.setsockopt(zmq.LINGER, 0)

            except Exception as e:
                logger.exception(str(e))
                # otherwise raise value error if errored
                if self.__secure_mode:
                    logger.warning(
                        "Failed to activate ZMQ Security Mechanism: `{}` for this address!"
                        .format(valid_security_mech[self.__secure_mode]))
                if self.__multiserver_mode:
                    raise ValueError(
                        "[NetGear:ERROR] :: Multi-Server Mode, failed to connect to ports: {} with pattern: {}! Kindly recheck all parameters."
                        .format(str(port), pattern))
                else:
                    raise ValueError(
                        "[NetGear:ERROR] :: Failed to bind address: {} and pattern: {}! Kindly recheck all parameters."
                        .format((protocol + "://" + str(address) + ":" +
                                 str(port)), pattern))

            # log and enable threaded queue mode
            if self.__logging:
                logger.debug(
                    "Threaded Queue Mode is enabled by default for NetGear.")
            # define deque and assign it to global var
            self.__queue = deque(maxlen=96)  # max len 96 to check overflow

            # initialize and start threading instance
            self.__thread = Thread(target=self.__update,
                                   name="NetGear",
                                   args=())
            self.__thread.daemon = True
            self.__thread.start()

            if self.__logging:
                # finally log progress
                logger.debug(
                    "Successfully Binded to address: {} with pattern: {}.".
                    format((protocol + "://" + str(address) + ":" + str(port)),
                           pattern))
                if self.__secure_mode:
                    logger.debug(
                        "Enabled ZMQ Security Mechanism: `{}` for this address, Successfully!"
                        .format(valid_security_mech[self.__secure_mode]))
                logger.debug(
                    "Multi-threaded Receive Mode is enabled Successfully!")
                logger.debug("Device Unique ID is {}.".format(self.__id))
                logger.debug("Receive Mode is activated successfully!")
        else:
            # otherwise default to `Send Mode`
            if address is None:
                address = "localhost"  # define address

            # check if multiserver_mode is enabled
            if self.__multiserver_mode:
                # check if unique server port address is assigned or not in multiserver_mode
                if port is None:
                    # raise error is not
                    raise ValueError(
                        "[NetGear:ERROR] :: Kindly provide a unique & valid port value at Server-end. For more information refer VidGear docs."
                    )
                else:
                    # otherwise log it
                    logger.debug(
                        "Enabling Multi-Server Mode at PORT: {} on this device!"
                        .format(port))
                    # assign value to global variable
                    self.port = port
            else:
                # otherwise assign local port address if None
                if port is None:
                    port = "5555"

            try:
                # initiate and handle secure mode
                if self.__secure_mode > 0:
                    # start an authenticator for this context
                    auth = ThreadAuthenticator(self.__msg_context)
                    auth.start()
                    auth.allow(str(address))  # allow current address

                    # check if `IronHouse` is activated
                    if self.__secure_mode == 2:
                        # tell authenticator to use the certificate from given valid dir
                        auth.configure_curve(
                            domain="*", location=self.__auth_publickeys_dir)
                    else:
                        # otherwise tell the authenticator how to handle the CURVE requests, if `StoneHouse` is activated
                        auth.configure_curve(domain="*",
                                             location=zmq.auth.CURVE_ALLOW_ANY)

                # initialize and define thread-safe messaging socket
                self.__msg_socket = self.__msg_context.socket(msg_pattern[0])

                if self.__pattern == 1:
                    # if pattern is 1, define additional flags
                    self.__msg_socket.REQ_RELAXED = True
                    self.__msg_socket.REQ_CORRELATE = True
                if self.__pattern == 2 and not (self.__secure_mode):
                    self.__msg_socket.set_hwm(
                        1)  # if pattern is 2, define additional optimizer

                # enable specified secure mode for the zmq socket
                if self.__secure_mode > 0:
                    # load client key
                    client_secret_file = os.path.join(
                        self.__auth_secretkeys_dir, "client.key_secret")
                    client_public, client_secret = zmq.auth.load_certificate(
                        client_secret_file)
                    # load  all CURVE keys
                    self.__msg_socket.curve_secretkey = client_secret
                    self.__msg_socket.curve_publickey = client_public
                    # load server key
                    server_public_file = os.path.join(
                        self.__auth_publickeys_dir, "server.key")
                    server_public, _ = zmq.auth.load_certificate(
                        server_public_file)
                    # inject public key to make a CURVE connection.
                    self.__msg_socket.curve_serverkey = server_public

                # connect socket to given protocol, address and port
                self.__msg_socket.connect(protocol + "://" + str(address) +
                                          ":" + str(port))

                # define socket options
                self.__msg_socket.setsockopt(zmq.LINGER, 0)

            except Exception as e:
                logger.exception(str(e))
                # log if errored
                if self.__secure_mode:
                    logger.warning(
                        "Failed to activate ZMQ Security Mechanism: `{}` for this address!"
                        .format(valid_security_mech[self.__secure_mode]))
                # raise value error
                raise ValueError(
                    "[NetGear:ERROR] :: Failed to connect address: {} and pattern: {}! Kindly recheck all parameters."
                    .format(
                        (protocol + "://" + str(address) + ":" + str(port)),
                        pattern))

            if self.__logging:
                # finally log progress
                logger.debug(
                    "Successfully connected to address: {} with pattern: {}.".
                    format((protocol + "://" + str(address) + ":" + str(port)),
                           pattern))
                if self.__secure_mode:
                    logger.debug(
                        "Enabled ZMQ Security Mechanism: `{}` for this address, Successfully!"
                        .format(valid_security_mech[self.__secure_mode]))
                logger.debug("This device Unique ID is {}.".format(self.__id))
                logger.debug(
                    "Send Mode is successfully activated and ready to send data!"
                )
Exemple #44
0
def main():
    """
    Parses command line input and then runs PubProxy and RouterProxy.
    """

    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-d",
        dest="debug",
        default=False,
        action="store_true",
        help="Enable debugging to console",
    )
    parser.add_argument(
        "--it",
        dest="proxy_base_port",
        type=int,
        default=5561,
        metavar="proxy_base_port",
        help="Interior proxy base port to bind to (->RTR<-, PUB, DLR, SUB)",
    )
    parser.add_argument(
        "--et",
        dest="be_base_port",
        type=int,
        default=5563,
        metavar="be_base_port",
        help="Base port of backend to connect to (RTR, PUB, ->DLR<-, SUB)",
    )
    parser.add_argument(
        "--ep",
        dest="be_ip",
        required=True,
        metavar="be_ip",
        help="IP of backend to connect to",
    )
    parser.add_argument(
        "--ip",
        dest="pxy_ip",
        required=True,
        metavar="pxy_ip",
        help="IP of internal proxy interface to bind to",
    )
    parser.add_argument(
        "--ak",
        dest="ak",
        required=True,
        metavar="appkey",
        help="The Curve public and private keys used by VMI apps",
    )
    parser.add_argument(
        "--bk",
        dest="bk",
        required=True,
        metavar="bekey",
        help="The Curve public and private keys for the backend",
    )
    args = parser.parse_args()
    print(f'{"#"*10}\nmain, starting Facilities with args: {args}\n{"#"*10}')

    if not os.path.isfile(args.ak) or not os.path.isfile(args.bk):
        print(f"ERROR: either {args.ak} or {args.bk} is is missing!")
        sys.exit()
    kp = {"be_key": args.bk, "app_key": args.ak}
    print(f"startup: keys OK")

    context = zmq.Context(io_threads=8)

    auth = ThreadAuthenticator(context)
    auth.start()
    auth.configure_curve(domain="*", location=zmq.auth.CURVE_ALLOW_ANY)

    proxy = RouterProxyRuntime(
        context,
        kp,
        debug=args.debug,
        pxy_ip=args.pxy_ip,
        proxy_base_port=args.proxy_base_port,
        be_ip=args.be_ip,
        be_base_port=args.be_base_port,
    )
    proxy.start()
    pubrelay = PubProxyRuntime(
        context,
        kp,
        debug=args.debug,
        pxy_ip=args.pxy_ip,
        proxy_base_port=args.proxy_base_port,
        be_ip=args.be_ip,
        be_base_port=args.be_base_port,
    )
    pubrelay.start()

    try:
        while True:
            tprintn(".")
            time.sleep(1)
    except KeyboardInterrupt:
        print("exiting...")
        auth.stop()
        context.term()
Exemple #45
0
#!/usr/bin/env python

import zmq
import zmq.auth
from zmq.auth.thread import ThreadAuthenticator

context = zmq.Context()
auth = ThreadAuthenticator(context)
auth.start()
#auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY)
auth.configure_curve(domain='*', location='authorized_keys')

socket = context.socket(zmq.REP)
socket.curve_server = True
socket.curve_publickey, socket.curve_secretkey = zmq.auth.load_certificate('keys/server.key_secret')
socket.bind("tcp://*:{}".format(53487))

while True:
    msg = socket.recv()
    print("Received request: ", msg)
    socket.send(b'ok')

auth.stop()
Exemple #46
0
def secure_srv(q_param, q_mgmt):
    #on thread start create current crypto key
    local = os.urandom(crypto_secretbox_KEYBYTES)
    # These directories are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')

    if not (os.path.exists(public_keys_dir)
            and os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - add certificat first")
        sys.exit(1)

    ctx = zmq.Context()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(context=ctx, encoding='utf-8')
    auth.start()
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    server = ctx.socket(zmq.PUB)
    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(
        server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True
    server.bind('tcp://*:5556')
    while (True):
        if not q_mgmt.empty():
            print "we rcv a mgmt msg"
            msg = q_mgmt.get()
            if msg.action == 0:
                print "we have to restart auth"
                auth.stop()
                auth = ThreadAuthenticator(context=ctx, encoding='utf-8')
                auth.start()
                auth.configure_curve(domain='*', location=public_keys_dir)
                print "Auth restarted"
        if not q_param.empty():
            print "we rcv a param msg"
            p = q_param.get()
            if p.t == 0:
                local = p.v
            #send new parameters with seq
            s_snd = struct.Struct('! B B H H H I')
            data = s_snd.pack(1, 6, 4, len(p.v), p.t, p.seq)
            server.send(data + str(p.v))
        #loop send key+seq if no new params
        key_param = Params(0, local, random.randint(0, max_int32_seq))
        s_snd = struct.Struct('! B B H H H I')
        data = s_snd.pack(1, 6, 4, len(key_param.v), key_param.t,
                          key_param.seq)
        server.send(data + str(key_param.v))
        time.sleep(2)  # avoid "as fast as possible" loop

    # stop auth thread
    auth.stop()
    # stop zmq context
    ctx.destroy()
    return
Exemple #47
0
class Ironhouse:

    auth_port = os.getenv('AUTH_PORT', 4523)
    keyname = os.getenv('HOST_NAME', 'ironhouse')
    authorized_nodes = {}
    base_dir = 'certs/{}'.format(keyname)
    keys_dir = join(base_dir, 'certificates')
    authorized_keys_dir = join(base_dir, 'authorized_keys')
    ctx = None
    auth = None
    daemon_auth = None

    def __init__(self,
                 sk=None,
                 auth_validate=None,
                 wipe_certs=False,
                 auth_port=None,
                 keyname=None,
                 *args,
                 **kwargs):
        if auth_validate: self.auth_validate = auth_validate
        else: self.auth_validate = Ironhouse.auth_validate
        self.auth_port = auth_port or self.auth_port
        self.keyname = keyname or Ironhouse.keyname
        self.authorized_keys = {}
        self.pk2vk = {}
        self.vk, self.public_key, self.secret = self.generate_certificates(
            sk, wipe_certs=wipe_certs)

    @classmethod
    def vk2pk(cls, vk):
        return encode(
            VerifyKey(
                bytes.fromhex(vk)).to_curve25519_public_key()._public_key)

    @classmethod
    def generate_certificates(cls, sk_hex, wipe_certs=False):
        sk = SigningKey(seed=bytes.fromhex(sk_hex))
        vk = sk.verify_key.encode().hex()
        public_key = cls.vk2pk(vk)
        private_key = crypto_sign_ed25519_sk_to_curve25519(
            sk._signing_key).hex()

        for d in [cls.keys_dir, cls.authorized_keys_dir]:
            if wipe_certs and exists(d):
                shutil.rmtree(d)
            os.makedirs(d, exist_ok=True)

        if wipe_certs:
            _, secret = cls.create_from_private_key(private_key)

            for key_file in os.listdir(cls.keys_dir):
                if key_file.endswith(".key"):
                    shutil.move(join(cls.keys_dir, key_file),
                                join(cls.authorized_keys_dir, '.'))

            if exists(cls.keys_dir):
                shutil.rmtree(cls.keys_dir)

            log.info('Generated CURVE certificate files!')

        return vk, public_key, secret

    @classmethod
    def create_from_private_key(cls, private_key):
        priv = PrivateKey(bytes.fromhex(private_key))
        publ = priv.public_key
        public_key = encode(publ._public_key)
        secret = encode(priv._private_key)

        base_filename = join(cls.keys_dir, cls.keyname)
        public_key_file = "{0}.key".format(base_filename)
        now = datetime.datetime.now()

        zmq.auth.certs._write_key_file(
            public_key_file, zmq.auth.certs._cert_public_banner.format(now),
            public_key)

        return public_key, secret

    def add_public_key(self, public_key):
        if self.public_key == public_key: return
        keyname = decode(public_key).hex()
        base_filename = join(self.authorized_keys_dir, keyname)
        public_key_file = "{0}.key".format(base_filename)
        now = datetime.datetime.now()

        if exists(public_key_file):
            log.debug('Public cert for {} has already been created.'.format(
                public_key))
            return

        os.makedirs(self.authorized_keys_dir, exist_ok=True)
        log.info(
            'Adding new public key cert {} to the system.'.format(public_key))

        zmq.auth.certs._write_key_file(
            public_key_file, zmq.auth.certs._cert_public_banner.format(now),
            public_key)

        log.debug('{} has added {} to its authorized list'.format(
            os.getenv('HOST_IP', '127.0.0.1'), public_key))
        self.reconfigure_curve()
        self.authorized_keys[public_key] = True

    def remove_public_key(self, public_key):
        if self.public_key == public_key: return
        keyname = decode(public_key).hex()
        base_filename = join(self.authorized_keys_dir, keyname)
        public_key_file = "{0}.key".format(base_filename)
        if exists(public_key_file):
            os.remove(public_key_file)

        log.debug('{} has remove {} from its authorized list'.format(
            os.getenv('HOST_IP', '127.0.0.1'), public_key))
        self.reconfigure_curve()
        self.authorized_keys[public_key] = False

    @classmethod
    def secure_context(cls, async=False):
        if async:
            ctx = zmq.asyncio.Context()
            auth = AsyncioAuthenticator(ctx)
            auth.log = log  # The constructor doesn't have "log" like its synchronous counter-part
        else:
            ctx = zmq.Context()
            auth = ThreadAuthenticator(ctx, log=log)
        auth.start()
        return ctx, auth
Exemple #48
0
import zmq
import zmq.auth
from zmq.auth.thread import ThreadAuthenticator
context = zmq.Context()
server = context.socket(zmq.REP)

auth = ThreadAuthenticator(context)
auth.start()
auth.allow('127.0.0.1')
auth.configure_plain(domain='*', passwords={'admin': 'password'})
server.plain_server = True
server.setsockopt(zmq.PLAIN_SERVER, 1)
server.connect('tcp://127.0.0.1:5556')

msg = server.recv_string()
server.send(b'Authenticated')

auth.stop()

Exemple #49
0
async def run():
    ''' Run Ironhouse example '''

    # These directories are generated by the generate_certificates script
    base_dir = Path(__file__).parent
    keys_dir = base_dir / 'certificates'
    public_keys_dir = base_dir / 'public_keys'
    secret_keys_dir = base_dir / 'private_keys'

    if not keys_dir.is_dir() or not public_keys_dir.is_dir(
    ) or not secret_keys_dir.is_dir():
        logging.critical(
            "Certificates are missing - run generate_certificates.py script first"
        )
        sys.exit(1)

    ctx = Context.instance()

    # Start an authenticator for this context.
    auth = AsyncioAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    server = ctx.socket(zmq.PUSH)

    server_secret_file = secret_keys_dir / "server.key_secret"
    server_public, server_secret = zmq.auth.load_certificate(
        server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True  # must come before bind
    server.bind('tcp://*:9000')

    client = ctx.socket(zmq.PULL)

    # We need two certificates, one for the client and one for
    # the server. The client must know the server's public key
    # to make a CURVE connection.
    client_secret_file = secret_keys_dir / "client.key_secret"
    client_public, client_secret = zmq.auth.load_certificate(
        client_secret_file)
    client.curve_secretkey = client_secret
    client.curve_publickey = client_public

    server_public_file = public_keys_dir / "server.key"
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    # The client must know the server's public key to make a CURVE connection.
    client.curve_serverkey = server_public
    client.connect('tcp://127.0.0.1:9000')

    await server.send(b"Hello")

    if await client.poll(1000):
        msg = await client.recv()
        if msg == b"Hello":
            logging.info("Ironhouse test OK")
    else:
        logging.error("Ironhouse test FAIL")

    # close sockets
    server.close()
    client.close()
    # stop auth task
    auth.stop()
Exemple #50
0
class Ironhouse:
    def __init__(self,
                 sk=None,
                 auth_validate=None,
                 wipe_certs=False,
                 auth_port=None,
                 keyname=None,
                 *args,
                 **kwargs):
        self.auth_port = auth_port or os.getenv('AUTH_PORT', 4523)
        self.keyname = keyname or os.getenv('HOSTNAME',
                                            basename(splitext(__file__)[0]))
        self.base_dir = 'certs/{}'.format(self.keyname)
        self.keys_dir = os.path.join(self.base_dir, 'certificates')
        self.public_keys_dir = os.path.join(self.base_dir, 'public_keys')
        self.secret_keys_dir = os.path.join(self.base_dir, 'private_keys')
        self.secret_file = os.path.join(self.secret_keys_dir,
                                        "{}.key_secret".format(self.keyname))
        if auth_validate:
            self.auth_validate = auth_validate
        else:
            self.auth_validate = Ironhouse.auth_validate
        self.wipe_certs = wipe_certs
        if sk:
            self.generate_certificates(sk)
        self.public_key, self.secret = zmq.auth.load_certificate(
            self.secret_file)

    def vk2pk(self, vk):
        return encode(
            VerifyKey(
                bytes.fromhex(vk)).to_curve25519_public_key()._public_key)

    def generate_certificates(self, sk):
        sk = SigningKey(seed=bytes.fromhex(sk))
        self.vk = sk.verify_key.encode().hex()
        self.public_key = self.vk2pk(self.vk)
        private_key = crypto_sign_ed25519_sk_to_curve25519(
            sk._signing_key).hex()

        for d in [self.keys_dir, self.public_keys_dir, self.secret_keys_dir]:
            if self.wipe_certs and os.path.exists(d):
                shutil.rmtree(d)
            os.makedirs(d, exist_ok=True)

        if self.wipe_certs:
            self.create_from_private_key(private_key)

            # move public keys to appropriate directory
            for key_file in os.listdir(self.keys_dir):
                if key_file.endswith(".key"):
                    shutil.move(os.path.join(self.keys_dir, key_file),
                                os.path.join(self.public_keys_dir, '.'))

            # move secret keys to appropriate directory
            for key_file in os.listdir(self.keys_dir):
                if key_file.endswith(".key_secret"):
                    shutil.move(os.path.join(self.keys_dir, key_file),
                                os.path.join(self.secret_keys_dir, '.'))

            log.info('Generated CURVE certificate files!')

    def create_from_private_key(self, private_key):
        priv = PrivateKey(bytes.fromhex(private_key))
        publ = priv.public_key
        self.public_key = public_key = encode(publ._public_key)
        secret_key = encode(priv._private_key)

        base_filename = os.path.join(self.keys_dir, self.keyname)
        secret_key_file = "{0}.key_secret".format(base_filename)
        public_key_file = "{0}.key".format(base_filename)
        now = datetime.datetime.now()

        zmq.auth.certs._write_key_file(
            public_key_file, zmq.auth.certs._cert_public_banner.format(now),
            public_key)

        zmq.auth.certs._write_key_file(
            secret_key_file,
            zmq.auth.certs._cert_secret_banner.format(now),
            public_key,
            secret_key=secret_key)

    def create_from_public_key(self, public_key):
        if self.public_key == public_key:
            return
        keyname = decode(public_key).hex()
        base_filename = os.path.join(self.public_keys_dir, keyname)
        public_key_file = "{0}.key".format(base_filename)
        now = datetime.datetime.now()

        if os.path.exists(public_key_file):
            log.debug('Public cert for {} has already been created.'.format(
                public_key))
            return

        os.makedirs(self.public_keys_dir, exist_ok=True)
        log.info(
            'Adding new public key cert {} to the system.'.format(public_key))

        zmq.auth.certs._write_key_file(
            public_key_file, zmq.auth.certs._cert_public_banner.format(now),
            public_key)

    def secure_context(self, async=False):
        if async:
            ctx = zmq.asyncio.Context()
            auth = AsyncioAuthenticator(ctx)
        else:
            ctx = zmq.Context()
            auth = ThreadAuthenticator(ctx)
        auth.start()
        self.reconfigure_curve(auth)

        return ctx, auth
    def handle(self, *args, **options):
        if options['level'] == 'ERROR':
            self.logger.setLevel(logging.ERROR)
        elif options['level'] == 'WARN':
            self.logger.setLevel(logging.WARN)
        elif options['level'] == 'INFO':
            self.logger.setLevel(logging.INFO)
        else:
            self.logger.setLevel(logging.DEBUG)

        auth = None
        # Create the sockets
        context = zmq.Context()
        self.pull_socket = context.socket(zmq.PULL)
        self.controler = context.socket(zmq.ROUTER)

        if options['encrypt']:
            self.logger.info("Starting encryption")
            try:
                auth = ThreadAuthenticator(context)
                auth.start()
                self.logger.debug("Opening master certificate: %s", options['master_cert'])
                master_public, master_secret = zmq.auth.load_certificate(options['master_cert'])
                self.logger.debug("Using slaves certificates from: %s", options['slaves_certs'])
                auth.configure_curve(domain='*', location=options['slaves_certs'])
            except IOError as err:
                self.logger.error(err)
                auth.stop()
                return
            self.controler.curve_publickey = master_public
            self.controler.curve_secretkey = master_secret
            self.controler.curve_server = True
            self.pull_socket.curve_publickey = master_public
            self.pull_socket.curve_secretkey = master_secret
            self.pull_socket.curve_server = True

        self.pull_socket.bind(options['log_socket'])
        self.controler.bind(options['master_socket'])

        # Last access to the database for new jobs and cancelations
        last_db_access = 0

        # Poll on the sockets (only one for the moment). This allow to have a
        # nice timeout along with polling.
        poller = zmq.Poller()
        poller.register(self.pull_socket, zmq.POLLIN)
        poller.register(self.controler, zmq.POLLIN)

        # Mask signals and create a pipe that will receive a bit for each
        # signal received. Poll the pipe along with the zmq socket so that we
        # can only be interupted while reading data.
        (pipe_r, pipe_w) = os.pipe()
        flags = fcntl.fcntl(pipe_w, fcntl.F_GETFL, 0)
        fcntl.fcntl(pipe_w, fcntl.F_SETFL, flags | os.O_NONBLOCK)

        def signal_to_pipe(signumber, _):
            # Send the signal number on the pipe
            os.write(pipe_w, chr(signumber))

        signal.signal(signal.SIGHUP, signal_to_pipe)
        signal.signal(signal.SIGINT, signal_to_pipe)
        signal.signal(signal.SIGTERM, signal_to_pipe)
        signal.signal(signal.SIGQUIT, signal_to_pipe)
        poller.register(pipe_r, zmq.POLLIN)

        if os.path.exists('/etc/lava-server/worker.conf'):
            self.logger.error("[FAIL] lava-master must not be run on a remote worker!")
            self.controler.close(linger=0)
            self.pull_socket.close(linger=0)
            context.term()
            sys.exit(2)

        self.logger.info("[INIT] LAVA dispatcher-master has started.")
        self.logger.info("[INIT] Using protocol version %d", PROTOCOL_VERSION)

        while True:
            try:
                try:
                    # TODO: Fix the timeout computation
                    # Wait for data or a timeout
                    sockets = dict(poller.poll(TIMEOUT * 1000))
                except zmq.error.ZMQError:
                    continue

                if sockets.get(pipe_r) == zmq.POLLIN:
                    signum = ord(os.read(pipe_r, 1))
                    if signum == signal.SIGHUP:
                        self.logger.info("[POLL] SIGHUP received, restarting loggers")
                        self.logging_support()
                    else:
                        self.logger.info("[POLL] Received a signal, leaving")
                        break

                # Logging socket
                if sockets.get(self.pull_socket) == zmq.POLLIN:
                    self.logging_socket(options)

                # Garbage collect file handlers
                now = time.time()
                for job_id in self.logs.keys():  # pylint: disable=consider-iterating-dictionary
                    if now - self.logs[job_id].last_usage > FD_TIMEOUT:
                        self.logger.info("[%s] Closing log file", job_id)
                        self.logs[job_id].close()
                        del self.logs[job_id]

                # Command socket
                if sockets.get(self.controler) == zmq.POLLIN:
                    if not self.controler_socket():
                        continue

                # Check dispatchers status
                now = time.time()
                for hostname, dispatcher in self.dispatchers.iteritems():
                    if dispatcher.online and now - dispatcher.last_msg > DISPATCHER_TIMEOUT:
                        self.logger.error("[STATE] Dispatcher <%s> goes OFFLINE", hostname)
                        self.dispatchers[hostname].online = False
                        # TODO: DB: mark the dispatcher as offline and attached
                        # devices

                # Limit accesses to the database. This will also limit the rate of
                # CANCEL and START messages
                if now - last_db_access > DB_LIMIT:
                    last_db_access = now

                    # TODO: make this atomic
                    # Dispatch pipeline jobs with devices in Reserved state
                    self.process_jobs(options)

                    # Handle canceling jobs
                    self.handle_canceling()
            except (OperationalError, InterfaceError):
                self.logger.info("[RESET] database connection reset.")
                continue

        # Closing sockets and droping messages.
        self.logger.info("[CLOSE] Closing the sockets and dropping messages")
        self.controler.close(linger=0)
        self.pull_socket.close(linger=0)
        if options['encrypt']:
            auth.stop()
        context.term()
Exemple #52
0
async def run():
    ''' Run Ironhouse example '''

    # These directories are generated by the generate_certificates script
    base_dir = Path(__file__).parent
    keys_dir = base_dir / 'certificates'
    public_keys_dir = base_dir / 'public_keys'
    secret_keys_dir = base_dir / 'private_keys'

    if (
        not keys_dir.is_dir()
        or not public_keys_dir.is_dir()
        or not secret_keys_dir.is_dir()
    ):
        logging.critical(
            "Certificates are missing - run generate_certificates.py script first"
        )
        sys.exit(1)

    ctx = Context.instance()

    # Start an authenticator for this context.
    auth = AsyncioAuthenticator(ctx)
    auth.start()
    auth.allow('127.0.0.1')
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    server = ctx.socket(zmq.ROUTER)

    server_secret_file = secret_keys_dir / "server.key_secret"
    server_public, server_secret = zmq.auth.load_certificate(server_secret_file)
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True  # must come before bind
    server.bind('tcp://*:9000')

    client = ctx.socket(zmq.DEALER)

    # We need two certificates, one for the client and one for
    # the server. The client must know the server's public key
    # to make a CURVE connection.
    client_secret_file = secret_keys_dir / "client.key_secret"
    client_public, client_secret = zmq.auth.load_certificate(client_secret_file)
    client.curve_secretkey = client_secret
    client.curve_publickey = client_public

    server_public_file = public_keys_dir / "server.key"
    server_public, _ = zmq.auth.load_certificate(server_public_file)
    # The client must know the server's public key to make a CURVE connection.
    client.curve_serverkey = server_public
    client.connect('tcp://127.0.0.1:9000')

    await client.send(b"Hello")

    if await server.poll(1000):
        # use copy=False to allow access to message properties via the zmq.Frame API
        # default recv(copy=True) returns only bytes, discarding properties
        identity, msg = await server.recv_multipart(copy=False)
        logging.info(f"Received {msg.bytes} from {msg['User-Id']!r}")
        if msg.bytes == b"Hello":
            logging.info("Ironhouse test OK")
    else:
        logging.error("Ironhouse test FAIL")

    # close sockets
    server.close()
    client.close()
    # stop auth task
    auth.stop()
def secure_srv(q_param, q_mgmt):
    #on thread start create current crypto key
    local = os.urandom(crypto_secretbox_KEYBYTES)
    # These directories are generated by the generate_certificates script
    base_dir = os.path.dirname(__file__)
    public_keys_dir = os.path.join(base_dir, 'public_keys')
    secret_keys_dir = os.path.join(base_dir, 'private_keys')

    if not(os.path.exists(public_keys_dir) and
            os.path.exists(secret_keys_dir)):
        logging.critical("Certificates are missing - add certificat first")
        sys.exit(1)

    ctx = zmq.Context()

    # Start an authenticator for this context.
    auth = ThreadAuthenticator(context=ctx, encoding='utf-8')
    auth.start()
    # Tell authenticator to use the certificate in a directory
    auth.configure_curve(domain='*', location=public_keys_dir)

    server = ctx.socket(zmq.PUB)
    server_secret_file = os.path.join(secret_keys_dir, "server.key_secret")
    server_public, server_secret = zmq.auth.load_certificate(
        server_secret_file
        )
    server.curve_secretkey = server_secret
    server.curve_publickey = server_public
    server.curve_server = True
    server.bind('tcp://*:5556')
    while(True):
        if not q_mgmt.empty():
            print "we rcv a mgmt msg"
            msg = q_mgmt.get()
            if msg.action == 0:
                print "we have to restart auth"
                auth.stop()
                auth = ThreadAuthenticator(context=ctx, encoding='utf-8')
                auth.start()
                auth.configure_curve(domain='*', location=public_keys_dir)
                print "Auth restarted"
        if not q_param.empty():
            print "we rcv a param msg"
            p = q_param.get()
            if p.t == 0:
                local = p.v
            #send new parameters with seq
            s_snd = struct.Struct('! B B H H H I')
            data = s_snd.pack(1, 6, 4, len(p.v), p.t, p.seq)
            server.send(data+str(p.v))
        #loop send key+seq if no new params
        key_param = Params(0, local, random.randint(0, max_int32_seq))
        s_snd = struct.Struct('! B B H H H I')
        data = s_snd.pack(
            1,
            6,
            4,
            len(key_param.v),
            key_param.t,
            key_param.seq
            )
        server.send(data+str(key_param.v))
        time.sleep(2)  # avoid "as fast as possible" loop

    # stop auth thread
    auth.stop()
    # stop zmq context
    ctx.destroy()
    return