PageRenderTime 101ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/PickleRPCHandler.py

https://bitbucket.org/rfc1437/toolserver
Python | 82 lines | 60 code | 14 blank | 8 comment | 6 complexity | 573db71329646828cc8e1a591b89f027 MD5 | raw file
  1. # -*- Mode: Python -*-
  2. # pickle_handler is a RPC handler for medusa built on xmlrpc_handler that
  3. # uses base64 encoded pickles instead of XML
  4. #
  5. # this adaption was done by Georg Bauer <bauer@gws.ms>
  6. # See http://www.xml-rpc.com/
  7. # http://www.pythonware.com/products/xmlrpc/
  8. # Based on "xmlrpcserver.py" by Fredrik Lundh (fredrik@pythonware.com)
  9. from base64 import encodestring, decodestring
  10. try: from cPickle import dumps, loads
  11. except ImportError: from pickle import dumps, loads
  12. from zlib import compress, decompress
  13. from Toolserver.Config import config, hasCrypto
  14. from Toolserver.RPCHandler import rpc_handler, registerRPCHandler
  15. from Toolserver.Authentication import privatekeys, publickeys
  16. from Toolserver.Utils import logWarning, ForbiddenError
  17. randompool = None
  18. if hasCrypto:
  19. from Crypto.Cipher import Blowfish
  20. from Crypto.Util.randpool import RandomPool
  21. randompool = RandomPool(500)
  22. def genPassword():
  23. randompool.stir()
  24. secret = randompool.get_bytes(16)
  25. randompool.stir()
  26. return secret
  27. class pickle_handler(rpc_handler):
  28. _prefix = 'PYRPC'
  29. _name = 'PickleRPC'
  30. _mime_type = 'text/plain'
  31. def parse_request(self, data, request):
  32. key = request.get_header('X-PickleRPC-Secret')
  33. key = (decodestring(key),)
  34. key = privatekeys[config.serverhostname].decrypt(key)
  35. s = decodestring(data)
  36. b = Blowfish.new(key, Blowfish.MODE_CBC)
  37. s = b.decrypt(s)
  38. s = decompress(s)
  39. (method, args, kw) = loads(s)
  40. if not hasattr(request, '_my_secret'):
  41. request._my_secret = genPassword()
  42. return (args, kw, kw.keys(), method)
  43. def build_exception(self, request, excinfo, reason):
  44. (e, d, tb) = excinfo
  45. res = dumps(d, 1)
  46. res = compress(res)
  47. if not hasattr(request, '_my_secret'):
  48. request._my_secret = genPassword()
  49. b = Blowfish.new(request._my_secret, Blowfish.MODE_CBC)
  50. res = b.encrypt(res+' '*(8-len(res)%8))
  51. return encodestring(res)
  52. def build_result(self, request, method, result):
  53. res = dumps(result, 1)
  54. res = compress(res)
  55. if not hasattr(request, '_my_secret'):
  56. request._my_secret = genPassword()
  57. b = Blowfish.new(request._my_secret, Blowfish.MODE_CBC)
  58. res = b.encrypt(res+' '*(8-len(res)%8))
  59. return encodestring(res)
  60. def outgoing_header_hook(self, request, data):
  61. key = publickeys[request.get_header('X-TooFPy-Signer')].encrypt(request._my_secret, '')
  62. key = key[0]
  63. key = encodestring(key).strip().replace('\n','')
  64. request['X-PickleRPC-Secret'] = key
  65. if hasCrypto and config.allowpicklerpc and config.rsaauthenticate:
  66. registerRPCHandler(pickle_handler)