Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. __author__ = 'Me'
  2. import sys, json
  3. from twisted.internet import reactor, ssl, protocol
  4. from twisted.python import log
  5. from OpenSSL import SSL
  6. from twisted.web.server import Site
  7. from twisted.web.static import File
  8. from autobahn.twisted.websocket import WebSocketServerFactory, WebSocketServerProtocol, listenWS,http
  9. from autobahn.twisted.resource import WebSocketResource
  10. import hashlib
  11. import os,binascii
  12. import time
  13. from twisted.web.util import redirectTo
  14. from twisted.python import log
  15. from twisted.web.resource import Resource
  16. from time import sleep
  17.  
  18. blockedClients = []
  19.  
  20. def search(value, list,key):
  21.     return [element for element in list if element[key] == value]
  22.  
  23. class BroadcastServerProtocol(WebSocketServerProtocol):
  24.     global blockedClients
  25.     def onConnect(self,request):
  26.         print 'client connecting: '+self.peer
  27.         ip, port = self.transport.client
  28.         isclient = {"ip":ip}
  29.         connectiontime = time.time()
  30.         blocked = search(ip, blockedClients, 'ip')
  31. #check client on connect and deny access if he's added to block list
  32.         if blocked:
  33.             dude = blocked[0]
  34.             print (connectiontime-dude['time'])
  35.             if connectiontime-(dude['time']) > 60:
  36.                 blockedClients.remove(blocked[0])
  37.             else:
  38.                 raise http.HttpException(1008,"Nope")
  39.  
  40. #on client open send challenge
  41.     def onOpen(self):
  42.         print "connection opened"
  43.         self.challenge=binascii.b2a_hex(os.urandom(128))
  44.         self.sendMessage(json.dumps({"challenge": self.challenge}))
  45.  
  46.     def onMessage(self, payload, isBinary):
  47. #only send mmessages to clients that have been authorized
  48.         if(self in self.factory.clients):
  49.             if not isBinary:
  50.                 data = json.loads(payload)
  51.                 print data
  52.                 if data.has_key('Output'):
  53.                     output = data["Output"]
  54.                     current = factory.lighting.output_status()[int(output)]
  55.                     newval = not int(current)
  56.                     print(output,' ',current,' ',newval)
  57.                     factory.lighting.output_cmd(int(output), newval, False)
  58.         else: #if message was received from an unauthorized client check it's hash against local computed hash
  59.             #print self.challenge
  60.             hash_object = hashlib.sha256(self.challenge+'secret')
  61.             hex_dig = hash_object.hexdigest()
  62.             if(payload==hex_dig):
  63.                 self.factory.register(self)
  64.             else:
  65.                 self.sendMessage("Sorry UnAuthorized")
  66.                 self.failConnection(1008.,"Sorry UnAuthorized")
  67.                 ip, port = self.transport.client
  68.                 block = {"ip":ip, "time":time.time()}
  69.                 blockedClients.append(block)
  70.                 print 'blocked:{0}'.format(ip)
  71.  
  72.  
  73.     def connectionLost(self, reason):
  74.         WebSocketServerProtocol.connectionLost(self, reason)
  75.         self.factory.unregister(self)
  76.  
  77. class BroadcastServerFactory(WebSocketServerFactory):
  78.  
  79.     def __init__(self, url, debug=False, debugCodePaths=False):
  80.         WebSocketServerFactory.__init__(self, url, debug=debug, debugCodePaths=debugCodePaths)
  81.         self.clients = []
  82.        
  83.     def register(self, client):
  84.         if client not in self.clients:
  85.             self.clients.append(client)
  86.  
  87.     def unregister(self, client):
  88.         if client in self.clients:
  89.             print("unregistered client {}".format(client.peer))
  90.             self.clients.remove(client)
  91.  
  92.     def broadcast(self, msg):
  93.         print("broadcasting message '{}' ..".format(msg))
  94.         for c in self.clients:
  95.             c.sendMessage(msg.encode('utf8'))
  96.             print("message sent to {}".format(c.peer))
  97.  
  98. if __name__ == '__main__':
  99.  
  100.     if len(sys.argv) > 1 and sys.argv[1] == 'debug':
  101.         log.startLogging(sys.stdout)
  102.         debug = True
  103.     else:
  104.         debug = False
  105.     contextFactory = ssl.DefaultOpenSSLContextFactory('keys/server.key','keys/server.crt')
  106.     ServerFactory = BroadcastServerFactory
  107.     factory = ServerFactory("wss://localhost:9000", debug=True, debugCodePaths=True)
  108.     factory.protocol = BroadcastServerProtocol
  109.     listenWS(factory, contextFactory)
  110.     webdir = File("web/")
  111.     webdir.contentTypes['.crt'] = 'application/x-x509-ca-cert'
  112.     web = Site(webdir)
  113.     reactor.listenSSL(443,web,contextFactory)
  114.     print 'starting server'
  115.     reactor.run()