spacepaste

  1.  
  2. """ Implements various cloud servers simultaneously.
  3. Currently implements two servers:
  4. 1) DeviceHTTPServer: The IoT device uploads data to the cloud via this HTTP
  5. server.
  6. 2) WebPortalHTTPServer: A server for a user to access using a web browser
  7. to see data from the IoT device.
  8. All data is received from IoT devices and appended to a perpetually growing
  9. list. When a user browses to the web portal, they are presented with all of
  10. the data received so far.
  11. """
  12. """
  13. # GDB code to pause on ctrl+c
  14. # http://stackoverflow.com/questions/10239760/interrupt-pause-running-python-program-in-pdb
  15. def debug_signal_handler(signal, frame):
  16. import pdb
  17. pdb.set_trace()
  18. import signal
  19. signal.signal(signal.SIGINT, debug_signal_handler)
  20. """
  21. import OpenSSL
  22. import sys
  23. from twisted.internet import endpoints, reactor, ssl
  24. from twisted.python import log
  25. from twisted.python.modules import getModule
  26. from twisted.web import resource, server
  27. PORT_DEVICE_UPLOAD = 5555
  28. PORT_WEB_PORTAL = 5556
  29. # All temperature readings received from IoT device connections.
  30. temperature_readings = []
  31. class DeviceHTTPServer(resource.Resource):
  32. """ HTTP Server for IoT device to upload data.
  33. Stores response bodies in global list variable temperature_readings.
  34. """
  35. isLeaf = True
  36. def render_POST(self, request):
  37. print "Received something"
  38. #for header in request.responseHeaders.getAllRawHeaders():
  39. # request.responseHeaders.removeHeader(header[0])
  40. reading = request.content.read()
  41. print "Received:", reading
  42. temperature_readings.append(reading)
  43. return "" # Empty response
  44. class WebPortalHTTPServer(resource.Resource):
  45. """ HTTP Server for users to browse.
  46. Currently prints out all the data received so far from devices.
  47. """
  48. isLeaf = True
  49. def render_GET(self, request):
  50. # Print all of the readings so far.
  51. return ("<HTML><BODY>"
  52. + ''.join([str(t) for t in temperature_readings])
  53. + "</BODY></HTML>")
  54. log.startLogging(sys.stdout)
  55. # DeviceSite - The site the device connects to
  56. deviceSite = server.Site(DeviceHTTPServer())
  57. #endpoint = endpoints.TCP4ServerEndpoint(reactor, PORT_DEVICE_UPLOAD)
  58. #endpoint = endpoints.serverFromString(reactor,
  59. # "ssl:port=%d"
  60. # ":privateKey=certs/middlebox.key"
  61. # ":certKey=certs/middlebox.crt"
  62. # ":extraCertChain=certs/ca_send_chain.crt"
  63. # ":sslmethod=TLSv1_2_METHOD"
  64. # % (PORT_DEVICE_UPLOAD,))
  65. #endpoint.listen(deviceSite)
  66. def load_cert(file_name):
  67. filepath = getModule(__name__).filePath
  68. data = filepath.sibling('certs').child(file_name).getContent()
  69. return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, data)
  70. def load_key(file_name):
  71. filepath = getModule(__name__).filePath
  72. data = filepath.sibling('certs').child(file_name).getContent()
  73. return OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, data)
  74. client_cert = load_cert('client_for_server.crt')
  75. server_cert = load_cert('server.crt')
  76. server_key = load_key('server.key')
  77. chain_filenames = ['ca-int1.crt', 'ca-int2.crt']
  78. chain_certs = [load_cert(filename) for filename in chain_filenames]
  79. reactor.listenSSL(PORT_DEVICE_UPLOAD, deviceSite,
  80. ssl.CertificateOptions(privateKey=server_key,
  81. certificate=server_cert,
  82. extraCertChain=chain_certs,
  83. method=OpenSSL.SSL.TLSv1_2_METHOD,
  84. # verify=True,
  85. # requireCertificate=True,
  86. # caCerts=[client_cert]
  87. )
  88. )
  89. # PortalSite - The web site for browsers
  90. portalSite = server.Site(WebPortalHTTPServer())
  91. endpoint = endpoints.TCP4ServerEndpoint(reactor, PORT_WEB_PORTAL)
  92. endpoint.listen(portalSite)
  93. reactor.run()
  94.