5 # Copyright 2012 Intel Corporation.
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
11 # http://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
19 # Luc Yriarte <luc.yriarte@intel.com>
20 # Christophe Guiraud <christophe.guiraud@intel.com>
21 # Frederic Paut <frederic.paut@intel.com>
25 import argparse, dbus, json, sys
27 from twisted.internet import glib2reactor
28 # Configure the twisted mainloop to be run inside the glib mainloop.
29 # This must be done before importing the other twisted modules
30 glib2reactor.install()
31 from twisted.internet import reactor, defer
33 from autobahn.websocket import listenWS
34 from autobahn.wamp import exportRpc, WampServerFactory, WampCraServerProtocol
36 from dbus.mainloop.glib import DBusGMainLoop
41 gobject.threads_init()
47 from twisted.python import log
50 from xml.etree.ElementTree import XMLParser
52 ###############################################################################
61 ###############################################################################
63 ## Convert an ip or an IP mask (such as ip/24 or ip/255.255.255.0) in hex value (32bits)
66 if mask.rfind(".") == -1:
68 maskHex = (2**(int(mask))-1)
69 maskHex = maskHex << (32-int(mask))
71 raise Exception("Illegal mask (larger than 32 bits) " + mask)
73 maskField = mask.split(".")
74 # Check if mask has four fields (byte)
75 if len(maskField) != 4:
76 raise Exception("Illegal ip address / mask (should be 4 bytes) " + mask)
77 for maskQuartet in maskField:
78 byte = int(maskQuartet)
79 # Check if each field is really a byte
81 raise Exception("Illegal ip address / mask (digit larger than a byte) " + mask)
83 maskHex = maskHex << 8
84 maskHex = maskHex >> 8
87 ###############################################################################
90 Global cache of DBus connexions and signal handlers
93 self.dbusConnexions = {}
94 self.signalHandlers = {}
99 Disconnect signal handlers before resetting cache.
101 self.dbusConnexions = {}
102 # disconnect signal handlers
103 for key in self.signalHandlers:
104 self.signalHandlers[key].disconnect()
105 self.signalHandlers = {}
108 def dbusConnexion(self, busName):
109 if not self.dbusConnexions.has_key(busName):
110 if busName == "session":
111 self.dbusConnexions[busName] = dbus.SessionBus()
112 elif busName == "system":
113 self.dbusConnexions[busName] = dbus.SystemBus()
115 raise Exception("Error: invalid bus: %s" % busName)
116 return self.dbusConnexions[busName]
120 ###############################################################################
121 class DbusSignalHandler:
123 signal hash id as busName#senderName#objectName#interfaceName#signalName
125 def __init__(self, busName, senderName, objectName, interfaceName, signalName):
126 self.id = "#".join([busName, senderName, objectName, interfaceName, signalName])
127 # connect handler to signal
128 self.bus = cache.dbusConnexion(busName)
129 self.bus.add_signal_receiver(self.handleSignal, signalName, interfaceName, senderName, objectName)
132 def disconnect(self):
133 names = self.id.split("#")
134 self.bus.remove_signal_receiver(self.handleSignal, names[4], names[3], names[1], names[2])
137 def handleSignal(self, *args):
139 publish dbus args under topic hash id
141 factory.dispatch(self.id, json.dumps(args))
145 ###############################################################################
146 class DbusCallHandler:
148 deferred reply to return dbus results
150 def __init__(self, method, args):
152 self.request = defer.Deferred()
157 def callMethod(self):
159 dbus method async call
162 self.method(*self.args, reply_handler=self.dbusSuccess, error_handler=self.dbusError)
166 def dbusSuccess(self, *result):
168 return JSON string result array
170 self.request.callback(json.dumps(result))
174 def dbusError(self, error):
176 return dbus error message
178 self.request.errback(Exception(error.get_dbus_message()))
183 ################################################################################
186 Execute DynDBusClass generated code
188 def __init__(self, globalCtx, localCtx) :
189 self.exec_string = ""
190 self.exec_code = None
191 self.exec_code_valid = 1
192 self.indent_level = 0
193 self.indent_increment = 1
195 self.localCtx = localCtx
196 self.globalCtx = globalCtx
199 def append_stmt(self, stmt) :
200 self.exec_code_valid = 0
202 for x in range(0,self.indent_level):
203 self.exec_string = self.exec_string + ' '
204 self.exec_string = self.exec_string + stmt + '\n'
207 self.indent_level = self.indent_level + self.indent_increment
210 self.indent_level = self.indent_level - self.indent_increment
212 # compile : Compile exec_string into exec_code using the builtin
213 # compile function. Skip if already in sync.
215 if not self.exec_code_valid :
216 self.exec_code = compile(self.exec_string, "<string>", "exec")
217 self.exec_code_valid = True
220 if not self.exec_code_valid :
222 exec(self.exec_code, self.globalCtx, self.localCtx)
226 ################################################################################
227 class XmlCbParser: # The target object of the parser
230 def __init__(self, dynDBusClass):
231 self.dynDBusClass = dynDBusClass
233 def start(self, tag, attrib): # Called for each opening tag.
237 if (tag == 'interface'):
238 self.dynDBusClass.set_interface(attrib['name'])
241 if (tag == 'method'):
243 self.dynDBusClass.def_method(attrib['name'])
245 if (tag == 'signal'):
247 self.dynDBusClass.def_signal(attrib['name'])
250 # Set signature (in/out & name) for method
252 if (self.current == 'method'):
253 if (attrib.has_key('direction') == False):
254 attrib['direction'] = "in"
255 self.dynDBusClass.add_signature(attrib['name'],
259 if (self.current == 'signal'):
260 if (attrib.has_key('name') == False):
261 attrib['name'] = 'value'
262 self.dynDBusClass.add_signature(attrib['name'], 'in',
265 def end(self, tag): # Called for each closing tag.
266 if (tag == 'method'):
267 self.dynDBusClass.add_dbus_method()
268 self.dynDBusClass.add_body_method()
269 self.dynDBusClass.end_method()
270 if (tag == 'signal'):
271 self.dynDBusClass.add_dbus_signal()
272 self.dynDBusClass.add_body_signal()
273 self.dynDBusClass.end_method()
275 def data(self, data):
276 pass # We do not need to do anything with data.
277 def close(self): # Called when all data has been parsed.
282 ###############################################################################
283 def createClassName(objectPath):
284 return re.sub('/', '_', objectPath[1:])
286 ################################################################################
287 class DynDBusClass():
288 def __init__(self, className, globalCtx, localCtx):
289 self.xmlCB = XmlCbParser(self)
291 self.class_code = ExecCode(globalCtx, localCtx)
292 self.class_code.indent_increment = 4
293 self.class_code.append_stmt("import dbus")
294 self.class_code.append_stmt("\n")
295 self.class_code.append_stmt("class " + className + "(dbus.service.Object):")
296 self.class_code.indent()
298 ## Overload of __init__ method
299 self.def_method("__init__")
300 self.add_method("bus, callback=None, objPath='/sample', srvName='org.cloudeebus'")
301 self.add_stmt("self.bus = bus")
302 self.add_stmt("self.objPath = objPath")
303 self.add_stmt("self.srvName = srvName")
304 self.add_stmt("self.callback = callback")
305 self.add_stmt("dbus.service.Object.__init__(self, conn=bus, bus_name=srvName)")
308 ## Create 'add_to_connection' method
309 self.def_method("add_to_connection")
310 self.add_method("connection=None, path=None")
311 self.add_stmt("dbus.service.Object.add_to_connection(self, connection=self.bus, path=self.objPath)")
314 ## Create 'remove_from_connection' method
315 self.def_method("remove_from_connection")
316 self.add_method("connection=None, path=None")
317 self.add_stmt("dbus.service.Object.remove_from_connection(self, connection=None, path=self.objPath)")
320 def createDBusServiceFromXML(self, xml):
321 self.parser = XMLParser(target=self.xmlCB)
322 self.parser.feed(xml)
325 def set_interface(self, ifName):
328 def def_method(self, methodName):
329 self.methodToAdd = methodName
330 self.signalToAdd = None
331 self.args_str = str()
333 self.signature['name'] = str()
334 self.signature['in'] = str()
335 self.signature['out'] = str()
337 def def_signal(self, signalName):
338 self.methodToAdd = None
339 self.signalToAdd = signalName
340 self.args_str = str()
342 self.signature['name'] = str()
343 self.signature['in'] = str()
344 self.signature['out'] = str()
346 def add_signature(self, name, direction, signature):
347 if (direction == 'in'):
348 self.signature['in'] += signature
349 if (self.signature['name'] != str()):
350 self.signature['name'] += ", "
351 self.signature['name'] += name
352 if (direction == 'out'):
353 self.signature['out'] = signature
355 def add_method(self, args = None, async_success_cb = None, async_err_cb = None):
357 if (self.methodToAdd != None):
358 name = self.methodToAdd
360 name = self.signalToAdd
363 if (async_success_cb != None):
364 async_cb_str = async_success_cb
365 if (async_err_cb != None):
366 if (async_cb_str != str()):
368 async_cb_str += async_err_cb
370 parameters = self.args_str
371 if (async_cb_str != str()):
372 if (parameters != str()):
374 parameters +=async_cb_str
376 if (parameters != str()):
377 self.class_code.append_stmt("def " + name + "(self, %s):" % parameters)
379 self.class_code.append_stmt("def " + name + "(self):")
380 self.class_code.indent()
382 def end_method(self):
383 self.class_code.append_stmt("\n")
384 self.class_code.dedent()
386 def add_dbus_method(self):
387 decorator = '@dbus.service.method("' + self.ifName + '"'
388 if (self.signature.has_key('in') and self.signature['in'] != str()):
389 decorator += ", in_signature='" + self.signature['in'] + "'"
390 if (self.signature.has_key('out') and self.signature['out'] != str()):
391 decorator += ", out_signature='" + self.signature['out'] + "'"
392 decorator += ", async_callbacks=('dbus_async_cb', 'dbus_async_err_cb')"
394 self.class_code.append_stmt(decorator)
395 if (self.signature.has_key('name') and self.signature['name'] != str()):
396 self.add_method(self.signature['name'], async_success_cb='dbus_async_cb', async_err_cb='dbus_async_err_cb')
398 self.add_method(async_success_cb='dbus_async_cb', async_err_cb='dbus_async_err_cb')
400 def add_dbus_signal(self):
401 decorator = '@dbus.service.signal("' + self.ifName + '"'
402 if (self.signature.has_key('in') and self.signature['in'] != str()):
403 decorator += ", signature='" + self.signature['in'] + "'"
405 self.class_code.append_stmt(decorator)
406 if (self.signature.has_key('name') and self.signature['name'] != str()):
407 self.add_method(self.signature['name'])
411 def add_body_method(self):
412 if (self.methodToAdd != None):
413 if (self.args_str != str()):
414 self.class_code.append_stmt("self.callback(self.srvName,'" + self.methodToAdd + "', self.objPath, '" + self.ifName + "', " + "dbus_async_cb, dbus_async_err_cb, %s)" % self.args_str)
416 self.class_code.append_stmt("self.callback(self.srvName,'" + self.methodToAdd + "', self.objPath, '" + self.ifName + "', " + "dbus_async_cb, dbus_async_err_cb)")
418 def add_body_signal(self):
419 self.class_code.append_stmt("return") ## TODO: Remove and fix with code ad hoc
420 self.class_code.append_stmt("\n")
422 def add_stmt(self, stmt) :
423 self.class_code.append_stmt(stmt)
426 self.class_code.execute()
430 ###############################################################################
431 class CloudeebusService:
433 support for sending DBus messages and registering for DBus signals
435 def __init__(self, permissions):
436 self.permissions = {};
437 self.permissions['permissions'] = permissions['permissions']
438 self.permissions['authextra'] = permissions['authextra']
439 self.permissions['services'] = permissions['services']
440 self.proxyObjects = {}
441 self.proxyMethods = {}
442 self.pendingCalls = []
443 self.dynDBusClasses = {} # DBus class source code generated dynamically (a list because one by classname)
444 self.services = {} # DBus service created
445 self.serviceAgents = {} # Instantiated DBus class previously generated dynamically, for now, one by classname
446 self.servicePendingCalls = {} # JS methods called (and waiting for a Success/error response), containing 'methodId', (successCB, errorCB)
447 self.localCtx = locals()
448 self.globalCtx = globals()
450 self.patternDbus = re.compile('^dbus\.(\w+)')
451 self.patternDbusBoolean = re.compile('^dbus.Boolean\((\w+)\)$')
452 self.patternDbusByte = re.compile('^dbus.Byte\((\d+)\)$')
453 self.patternDbusInt16 = re.compile('^dbus.Int16\((\d+)\)$')
454 self.patternDbusInt32 = re.compile('^dbus.Int32\((\d+)\)$')
455 self.patternDbusInt64 = re.compile('^dbus.Int64\((\d+)\)$')
456 self.patternDbusUInt16 = re.compile('^dbus.UInt16\((\d+)\)$')
457 self.patternDbusUInt32 = re.compile('^dbus.UInt32\((\d+)\)$')
458 self.patternDbusUInt64 = re.compile('^dbus.UInt64\((\d+)\)$')
459 self.patternDbusDouble = re.compile('^dbus.Double\((\d+\.\d+)\)$')
461 def proxyObject(self, busName, serviceName, objectName):
463 object hash id as busName#serviceName#objectName
465 id = "#".join([busName, serviceName, objectName])
466 if not self.proxyObjects.has_key(id):
468 # check permissions, array.index throws exception
469 self.permissions['permissions'].index(serviceName)
470 bus = cache.dbusConnexion(busName)
471 self.proxyObjects[id] = bus.get_object(serviceName, objectName)
472 return self.proxyObjects[id]
475 def proxyMethod(self, busName, serviceName, objectName, interfaceName, methodName):
477 method hash id as busName#serviceName#objectName#interfaceName#methodName
479 id = "#".join([busName, serviceName, objectName, interfaceName, methodName])
480 if not self.proxyMethods.has_key(id):
481 obj = self.proxyObject(busName, serviceName, objectName)
482 self.proxyMethods[id] = obj.get_dbus_method(methodName, interfaceName)
483 return self.proxyMethods[id]
485 def decodeArgs( self, args ):
486 if isinstance( args, list ):
489 newArgs.append( self.decodeArgs( arg ))
491 elif isinstance( args, dict ):
493 for key, value in args.iteritems():
494 key = self.decodeArgs( key )
495 newValue = self.decodeArgs( value )
496 newDict[key] = newValue
498 elif isinstance( args, basestring ):
499 newArg = self.decodeDbusString( args )
504 def decodeDbusString( self, dbusString ):
505 matchDbus = self.patternDbus.match( dbusString )
512 "Boolean" : lambda x : dbus.Boolean( self.patternDbusBoolean.match( x ).group( 1 ).lower() in ("yes", "true", "t", "1")),
513 "Byte" : lambda x : dbus.Byte( int( self.patternDbusByte.match( x ).group( 1 ))),
514 "Int16" : lambda x : dbus.Int16( self.patternDbusInt16.match( x ).group( 1 )),
515 "Int32" : lambda x : dbus.Int32( self.patternDbusInt32.match( x ).group( 1 )),
516 "Int64" : lambda x : dbus.Int64( self.patternDbusInt64.match( x ).group( 1 )),
517 "UInt16" : lambda x : dbus.UInt16( self.patternDbusUInt16.match( x ).group( 1 )),
518 "UInt32" : lambda x : dbus.UInt32( self.patternDbusUInt32.match( x ).group( 1 )),
519 "UInt64" : lambda x : dbus.UInt64( self.patternDbusUInt64.match( x ).group( 1 )),
520 "Double" : lambda x : dbus.Double( self.patternDbusDouble.match( x ).group( 1 ))
521 }[matchDbus.group(1)](dbusString)
526 def dbusRegister(self, list):
528 arguments: bus, sender, object, interface, signal
531 raise Exception("Error: expected arguments: bus, sender, object, interface, signal)")
534 # check permissions, array.index throws exception
535 self.permissions['permissions'].index(list[1])
537 # check if a handler exists
538 sigId = "#".join(list)
539 if cache.signalHandlers.has_key(sigId):
542 # create a handler that will publish the signal
543 dbusSignalHandler = DbusSignalHandler(*list)
544 cache.signalHandlers[sigId] = dbusSignalHandler
546 return dbusSignalHandler.id
550 def dbusSend(self, list):
552 arguments: bus, destination, object, interface, message, [args]
554 # clear pending calls
555 for call in self.pendingCalls:
557 self.pendingCalls.remove(call)
560 raise Exception("Error: expected arguments: bus, destination, object, interface, message, [args])")
562 # parse JSON arg list
565 jsonArgs = json.loads(list[5])
566 print "JSON Arguments:", jsonArgs
568 args = self.decodeArgs( jsonArgs )
569 print "Decoded Arguments: ", args
571 # get dbus proxy method
572 method = self.proxyMethod(*list[0:5])
574 # use a deferred call handler to manage dbus results
575 dbusCallHandler = DbusCallHandler(method, args)
576 self.pendingCalls.append(dbusCallHandler)
577 return dbusCallHandler.callMethod()
581 def emitSignal(self, list):
583 arguments: agentObjectPath, signalName, args (to emit)
586 className = re.sub('/', '_', objectPath[1:])
589 jsonArgs = json.loads(list[2])
590 print "JSON Arguments:", jsonArgs
592 args = self.decodeArgs( jsonArgs )
593 print "Decoded Arguments: ", args
595 if (self.serviceAgents.has_key(className) == True):
596 exe_str = "self.serviceAgents['"+ className +"']."+ signalName + "("
598 exe_str += json.dumps(args[0])
600 exe_str += "," + json.dumps(idx)
602 eval(exe_str, self.globalCtx, self.localCtx)
604 raise Exception("No object path " + objectPath)
607 def returnMethod(self, list):
609 arguments: methodId, callIndex, success (=true, error otherwise), result (to return)
615 if (self.servicePendingCalls.has_key(methodId)):
616 cb = self.servicePendingCalls[methodId]['calls'][callIndex]
618 raise Exception("No pending call " + str(callIndex) + " for methodID " + methodId)
620 successCB = cb["successCB"]
626 errorCB = cb["errorCB"]
631 self.servicePendingCalls[methodId]['calls'][callIndex] = None
632 self.servicePendingCalls[methodId]['count'] = self.servicePendingCalls[methodId]['count'] - 1
633 if self.servicePendingCalls[methodId]['count'] == 0:
634 del self.servicePendingCalls[methodId]
636 raise Exception("No methodID " + methodId)
638 def srvCB(self, srvName, name, objPath, ifName, async_succes_cb, async_error_cb, *args):
639 methodId = srvName + "#" + objPath + "#" + ifName + "#" + name
640 cb = { 'successCB': async_succes_cb,
641 'errorCB': async_error_cb}
642 if methodId not in self.servicePendingCalls:
643 self.servicePendingCalls[methodId] = {'count': 0, 'calls': []}
646 pendingCallStr = json.dumps({'callIndex': len(self.servicePendingCalls[methodId]['calls']), 'args': args})
648 args = eval( str(args).replace("dbus.Byte", "dbus.Int16") )
649 pendingCallStr = json.dumps({'callIndex': len(self.servicePendingCalls[methodId]['calls']), 'args': args})
651 self.servicePendingCalls[methodId]['calls'].append(cb)
652 self.servicePendingCalls[methodId]['count'] = self.servicePendingCalls[methodId]['count'] + 1
653 factory.dispatch(methodId, pendingCallStr)
656 def serviceAdd(self, list):
658 arguments: busName, srvName
661 self.bus = cache.dbusConnexion( busName )
663 if not OPENDOOR and (SERVICELIST == [] or SERVICELIST != [] and self.permissions['services'] == None):
664 SERVICELIST.index(srvName)
666 if (self.services.has_key(srvName) == False):
667 self.services[srvName] = dbus.service.BusName(name = srvName, bus = self.bus)
671 def serviceRelease(self, list):
673 arguments: busName, srvName
676 if (self.services.has_key(srvName) == True):
677 self.services.pop(srvName)
680 raise Exception(srvName + " does not exist")
683 def serviceAddAgent(self, list):
685 arguments: objectPath, xmlTemplate
688 agentObjectPath = list[1]
689 xmlTemplate = list[2]
690 className = createClassName(agentObjectPath)
691 if (self.dynDBusClasses.has_key(className) == False):
692 self.dynDBusClasses[className] = DynDBusClass(className, self.globalCtx, self.localCtx)
693 self.dynDBusClasses[className].createDBusServiceFromXML(xmlTemplate)
694 self.dynDBusClasses[className].declare()
696 ## Class already exist, instanciate it if not already instanciated
697 if (self.serviceAgents.has_key(className) == False):
698 self.serviceAgents[className] = eval(className + "(self.bus, callback=self.srvCB, objPath='" + agentObjectPath + "', srvName='" + srvName + "')", self.globalCtx, self.localCtx)
700 self.serviceAgents[className].add_to_connection()
701 return (agentObjectPath)
704 def serviceDelAgent(self, list):
706 arguments: objectPath, xmlTemplate
708 agentObjectPath = list[0]
709 className = createClassName(agentObjectPath)
711 if (self.serviceAgents.has_key(className)):
712 self.serviceAgents[className].remove_from_connection()
713 self.serviceAgents.pop(className)
715 raise Exception(agentObjectPath + " doesn't exist!")
717 return (agentObjectPath)
720 def getVersion(self):
722 return current version string
728 ###############################################################################
729 class CloudeebusServerProtocol(WampCraServerProtocol):
731 connexion and session authentication management
734 def onSessionOpen(self):
735 # CRA authentication options
736 self.clientAuthTimeout = 0
737 self.clientAuthAllowAnonymous = OPENDOOR
738 # CRA authentication init
739 WampCraServerProtocol.onSessionOpen(self)
742 def getAuthPermissions(self, key, extra):
743 return {'permissions': extra.get("permissions", None),
744 'authextra': extra.get("authextra", None),
745 'services': extra.get("services", None)}
747 def getAuthSecret(self, key):
748 secret = CREDENTIALS.get(key, None)
751 # secret must be of str type to be hashed
755 def onAuthenticated(self, key, permissions):
760 for netfilter in NETMASK:
761 ipHex=ipV4ToHex(self.peer.host)
762 ipAllowed = (ipHex & netfilter['mask']) == netfilter['ipAllowed'] & netfilter['mask']
766 raise Exception("host " + self.peer.host + " is not allowed!")
767 # check authentication key
769 raise Exception("Authentication failed")
770 # check permissions, array.index throws exception
771 if (permissions['permissions'] != None):
772 for req in permissions['permissions']:
773 WHITELIST.index(req);
774 # check allowed service creation, array.index throws exception
775 if (permissions['services'] != None):
776 for req in permissions['services']:
777 SERVICELIST.index(req);
778 # create cloudeebus service instance
779 self.cloudeebusService = CloudeebusService(permissions)
780 # register it for RPC
781 self.registerForRpc(self.cloudeebusService)
782 # register for Publish / Subscribe
783 self.registerForPubSub("", True)
786 def connectionLost(self, reason):
787 WampCraServerProtocol.connectionLost(self, reason)
788 if factory.getConnectionCount() == 0:
793 ###############################################################################
795 if __name__ == '__main__':
799 parser = argparse.ArgumentParser(description='Javascript DBus bridge.')
800 parser.add_argument('-v', '--version', action='store_true',
801 help='print version and exit')
802 parser.add_argument('-d', '--debug', action='store_true',
803 help='log debug info on standard output')
804 parser.add_argument('-o', '--opendoor', action='store_true',
805 help='allow anonymous access to all services')
806 parser.add_argument('-p', '--port', default='9000',
808 parser.add_argument('-c', '--credentials',
809 help='path to credentials file')
810 parser.add_argument('-w', '--whitelist',
811 help='path to whitelist file (DBus services to use)')
812 parser.add_argument('-s', '--servicelist',
813 help='path to servicelist file (DBus services to export)')
814 parser.add_argument('-n', '--netmask',
815 help='netmask,IP filter (comma separated.) eg. : -n 127.0.0.1,192.168.2.0/24,10.12.16.0/255.255.255.0')
817 args = parser.parse_args(sys.argv[1:])
820 print("Cloudeebus version " + VERSION)
824 log.startLogging(sys.stdout)
826 OPENDOOR = args.opendoor
829 jfile = open(args.credentials)
830 CREDENTIALS = json.load(jfile)
834 jfile = open(args.whitelist)
835 WHITELIST = json.load(jfile)
839 jfile = open(args.servicelist)
840 SERVICELIST = json.load(jfile)
844 iplist = args.netmask.split(",")
846 if ip.rfind("/") != -1:
852 mask = "255.255.255.255"
853 NETMASK.append( {'ipAllowed': ipV4ToHex(ipAllowed), 'mask' : ipV4ToHex(mask)} )
855 uri = "ws://localhost:" + args.port
857 factory = WampServerFactory(uri, debugWamp = args.debug)
858 factory.protocol = CloudeebusServerProtocol
859 factory.setProtocolOptions(allowHixie76 = True)
863 DBusGMainLoop(set_as_default=True)