-
Notifications
You must be signed in to change notification settings - Fork 631
/
ioloop-ironhouse-server.py
102 lines (79 loc) · 3.21 KB
/
ioloop-ironhouse-server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python
'''
Ironhouse extends Stonehouse with client public key authentication.
This is the strongest security model we have today, protecting against every
attack we know about, except end-point attacks (where an attacker plants
spyware on a machine to capture data before it's encrypted, or after it's
decrypted).
This example demonstrates using the IOLoopAuthenticator.
Author: Chris Laws
'''
import datetime
import logging
import os
import sys
import zmq
import zmq.auth
from zmq.eventloop import ioloop, zmqstream
class IronhouseServer(object):
''' Ironhouse Server '''
def __init__(self, context, server_cert_file, endpoint='tcp://*:9000'):
self.context = context
self.endpoint = endpoint
self.socket = None
self.stream = None
self.public, self.secret = zmq.auth.load_certificate(server_cert_file)
self.loop = ioloop.IOLoop.instance()
def start(self):
self.socket = self.context.socket(zmq.ROUTER)
# most socket options must be set before bind/connect
self.socket.curve_secretkey = self.secret
self.socket.curve_publickey = self.public
self.socket.curve_server = True
self.stream = zmqstream.ZMQStream(self.socket)
self.stream.on_recv(self.on_message)
self.stream.bind('tcp://*:9000')
def stop(self):
if self.send_timer:
self.send_timer.stop()
self.stream.close()
def on_message(self, frames):
logging.info("received request")
identity = frames[0]
msg = [identity, str(datetime.datetime.now()).encode('utf8')]
logging.debug("sending reply")
self.stream.send_multipart(msg)
# Shutdown after sending reply msg message
self.loop.add_timeout(self.loop.time()+.1, ioloop.IOLoop.instance().stop)
if __name__ == '__main__':
if zmq.zmq_version_info() < (4,0):
raise RuntimeError("Security is not supported in libzmq version < 4.0. libzmq version {0}".format(zmq.zmq_version()))
if '-v' in sys.argv:
level = logging.DEBUG
else:
level = logging.INFO
logging.basicConfig(level=level, format="[%(levelname)s] %(message)s")
# These direcotries are generated by the generate_keys 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(keys_dir) and os.path.exists(keys_dir)):
logging.critical("Certificates are missing - run generate_certificates script first")
sys.exit(1)
ctx = zmq.Context().instance()
# Start an authenticator for this context.
auth = zmq.auth.IOLoopAuthenticator(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_cert_file = os.path.join(secret_keys_dir, "server.key_secret")
iron_server = IronhouseServer(ctx, server_cert_file)
iron_server.start()
try:
ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
pass
# stop auth thread
auth.stop()