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()
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()
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_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()
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()
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()
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()
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()
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()
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)
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 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 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")
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")
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 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
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(): ''' 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()
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()
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"}')
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()
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!" )
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)
else: print "Unknown argument: %s" % sys.argv[1] sys.exit() # certificates 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') # zmq setup context = zmq.Context() # auth setup auth = ThreadAuthenticator(context) auth.start() auth.allow('127.0.0.1') auth.configure_curve(domain='*', location=public_keys_dir) # will accept incoming connections frontend = context.socket(zmq.ROUTER) # server auth setup server_secret_file = os.path.join(secret_keys_dir, "server.key_secret") server_public, server_secret = zmq.auth.load_certificate(server_secret_file) frontend.curve_secretkey = server_secret frontend.curve_publickey = server_public frontend.curve_server = True frontend.bind("tcp://*:5555") # will connect to the worker threads
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()
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()