diff options
| author | Simeon Simeonov | 2015-04-14 10:38:43 +0200 |
|---|---|---|
| committer | Simeon Simeonov | 2015-04-14 10:38:43 +0200 |
| commit | 4aea82a1aef53c28110cc45c734b835efdc361b3 (patch) | |
| tree | 7f380d3a8982364081f0d32904454a0878f81782 /beinc_server_xmlrpc.py | |
| parent | d606cbfc4932dd67cdb272a32e8103998fd3312a (diff) | |
beinc_config_sample.json beinc_config_sample.json.readme and beinc_server_xmlrpc.py almost complete
Diffstat (limited to 'beinc_server_xmlrpc.py')
| -rwxr-xr-x | beinc_server_xmlrpc.py | 75 |
1 files changed, 54 insertions, 21 deletions
diff --git a/beinc_server_xmlrpc.py b/beinc_server_xmlrpc.py index a9d0fa5..39cf422 100755 --- a/beinc_server_xmlrpc.py +++ b/beinc_server_xmlrpc.py | |||
| @@ -27,6 +27,8 @@ import sys | |||
| 27 | 27 | ||
| 28 | import OpenSSL | 28 | import OpenSSL |
| 29 | 29 | ||
| 30 | from functools import wraps | ||
| 31 | |||
| 30 | from twisted.web import xmlrpc, server | 32 | from twisted.web import xmlrpc, server |
| 31 | from twisted.internet import protocol, reactor, ssl | 33 | from twisted.internet import protocol, reactor, ssl |
| 32 | from twisted.python.filepath import FilePath | 34 | from twisted.python.filepath import FilePath |
| @@ -49,7 +51,7 @@ except ImportError as e: | |||
| 49 | 51 | ||
| 50 | 52 | ||
| 51 | __author__ = 'Simeon Simeonov' | 53 | __author__ = 'Simeon Simeonov' |
| 52 | __version__ = '1.1' | 54 | __version__ = '2.0' |
| 53 | __license__ = 'GPL3' | 55 | __license__ = 'GPL3' |
| 54 | 56 | ||
| 55 | 57 | ||
| @@ -57,6 +59,17 @@ BEINC_OSD_TYPE_NONE = 0 | |||
| 57 | BEINC_OSD_TYPE_PYNOTIFY = 1 | 59 | BEINC_OSD_TYPE_PYNOTIFY = 1 |
| 58 | BEINC_OSD_TYPE_PYOSD = 2 | 60 | BEINC_OSD_TYPE_PYOSD = 2 |
| 59 | 61 | ||
| 62 | BEINC_SSL_METHODS = {'SSLv3': OpenSSL.SSL.SSLv3_METHOD, | ||
| 63 | 'TLSv1': OpenSSL.SSL.TLSv1_METHOD} | ||
| 64 | try: | ||
| 65 | errstr = "Warning: Current Twisted / OpenSSL version doesn't support TLSv1.1" | ||
| 66 | BEINC_SSL_METHODS.update({'TLSv1_1': OpenSSL.SSL.TLSv1_1_METHOD}) | ||
| 67 | errstr = "Warning: Current Twisted / OpenSSL version doesn't support TLSv1.2" | ||
| 68 | BEINC_SSL_METHODS.update({'TLSv1_2': OpenSSL.SSL.TLSv1_2_METHOD}) | ||
| 69 | except: | ||
| 70 | sys.stderr.write(errstr + '\n') | ||
| 71 | |||
| 72 | |||
| 60 | class BEINCInstance(object): | 73 | class BEINCInstance(object): |
| 61 | """ | 74 | """ |
| 62 | Represents a single server-instance | 75 | Represents a single server-instance |
| @@ -201,6 +214,7 @@ def beinc_login_required(method): | |||
| 201 | decorator for checking login credentials | 214 | decorator for checking login credentials |
| 202 | """ | 215 | """ |
| 203 | 216 | ||
| 217 | @wraps(method) | ||
| 204 | def wrapper(self, resource_name, password, *args, **kwargs): | 218 | def wrapper(self, resource_name, password, *args, **kwargs): |
| 205 | try: | 219 | try: |
| 206 | instance = self.instances[resource_name] | 220 | instance = self.instances[resource_name] |
| @@ -268,11 +282,12 @@ class XMLRPCNotifyServer(xmlrpc.XMLRPC): | |||
| 268 | e)) | 282 | e)) |
| 269 | raise xmlrpc.Fault(500, 'Unable to send message') | 283 | raise xmlrpc.Fault(500, 'Unable to send message') |
| 270 | 284 | ||
| 285 | @beinc_login_required | ||
| 271 | def xmlrpc_pull(self, resource_name, password): | 286 | def xmlrpc_pull(self, resource_name, password): |
| 272 | """ | 287 | """ |
| 273 | Return sum of arguments. | 288 | Return sum of arguments. |
| 274 | """ | 289 | """ |
| 275 | instance = self.__instances[args[0]] | 290 | instance = self.__instances[resource_name] |
| 276 | if not instance.queueable: | 291 | if not instance.queueable: |
| 277 | raise xmlrpc.Fault( | 292 | raise xmlrpc.Fault( |
| 278 | 405, | 293 | 405, |
| @@ -323,30 +338,48 @@ def main(): | |||
| 323 | with open(args.config_file, 'r') as fp: | 338 | with open(args.config_file, 'r') as fp: |
| 324 | config_dict = json.load(fp) | 339 | config_dict = json.load(fp) |
| 325 | except Exception as e: | 340 | except Exception as e: |
| 326 | sys.stderr.write('Unable to parse {0}: {1}'.format(args.config_file, | 341 | sys.stderr.write('Unable to parse {0}: {1}\n'.format(args.config_file, |
| 327 | e)) | 342 | e)) |
| 328 | sys.exit(errno.EIO) | 343 | sys.exit(errno.EIO) |
| 329 | ssl_certificate = config_dict['server']['general']['ssl_certificate'] | 344 | try: |
| 330 | ssl_private_key = config_dict['server']['general']['ssl_private_key'] | 345 | if config_dict.get(config_version) != 2: |
| 331 | try: | 346 | sys.stderr.write( |
| 347 | 'Incompatible or missing config-file version for {0}\n'.format( | ||
| 348 | args.config_file)) | ||
| 349 | sys.exit(1) | ||
| 350 | ssl_certificate = config_dict['server']['general'].get( | ||
| 351 | 'ssl_certificate') | ||
| 352 | ssl_private_key = config_dict['server']['general'].get( | ||
| 353 | 'ssl_private_key') | ||
| 354 | ssl_method_str = config_dict['server']['general'].get( | ||
| 355 | 'ssl_method', 'auto') | ||
| 356 | ssl_acceptable_ciphers_str = config_dict['server']['general'].get( | ||
| 357 | 'ssl_acceptable_ciphers', 'auto') | ||
| 332 | beinc_server = XMLRPCNotifyServer(config_dict) | 358 | beinc_server = XMLRPCNotifyServer(config_dict) |
| 333 | cert_path = FilePath( | 359 | if ssl_certificate and ssl_private_key: |
| 334 | config_dict['server']['general']['ssl_certificate']) | 360 | # SSL connection |
| 335 | key_path = FilePath( | 361 | cert_path = FilePath(ssl_certificate) |
| 336 | config_dict['server']['general']['ssl_private_key']) | 362 | key_path = FilePath(ssl_private_key) |
| 337 | private_certificate = ssl.PrivateCertificate.loadPEM( | 363 | private_certificate = ssl.PrivateCertificate.loadPEM( |
| 338 | key_path.getContent() + cert_path.getContent()) | 364 | key_path.getContent() + cert_path.getContent()) |
| 339 | options = private_certificate.options() | 365 | options = private_certificate.options() |
| 340 | options.method = OpenSSL.SSL.TLSv1_2_METHOD | 366 | ssl_method = BEINC_SSL_METHODS.get(ssl_method_str) |
| 341 | # options.acceptableCiphers = | 367 | if ssl_method: |
| 342 | # ssl.AcceptableCiphers.fromOpenSSLCipherString('EXP-RC4-MD5') | 368 | options.method = ssl_method |
| 343 | reactor.listenSSL(args.port, | 369 | if ssl_acceptable_ciphers_str.lower() != 'auto': |
| 344 | server.Site(beinc_server), | 370 | options.acceptableCiphers = ssl.AcceptableCiphers.fromOpenSSLCipherString( |
| 345 | options, | 371 | ssl_acceptable_ciphers_str) |
| 346 | interface=args.hostname) | 372 | reactor.listenSSL(args.port, |
| 373 | server.Site(beinc_server), | ||
| 374 | options, | ||
| 375 | interface=args.hostname) | ||
| 376 | else: | ||
| 377 | reactor.listenTCP(args.port, | ||
| 378 | server.Site(beinc_server), | ||
| 379 | interface=args.hostname) | ||
| 347 | reactor.run() | 380 | reactor.run() |
| 348 | except Exception as e: | 381 | except Exception as e: |
| 349 | sys.stderr.write("WebServer error: {0}".format(e)) | 382 | sys.stderr.write('WebServer error: {0}\n'.format(e)) |
| 350 | sys.exit(1) | 383 | sys.exit(1) |
| 351 | sys.exit(0) | 384 | sys.exit(0) |
| 352 | 385 | ||
