auth_xmlrpc.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. # Copyright 2006 BitTorrent, Inc. All Rights Reserved.
  2. #
  3. # XML-RPC that supports public key encryption and authentication.
  4. # Author: David Harrison
  5. from BTL.reactor_magic import reactor
  6. from twisted.web import xmlrpc
  7. from twisted.internet.ssl import SSL
  8. from twisted.internet import ssl
  9. debug = False
  10. ## Keep these next two commented out classes. They can be useful for
  11. ## spying on calls.
  12. class AuthQueryProtocol(xmlrpc.QueryProtocol):
  13. def connectionMade(self):
  14. if debug:
  15. print "connectionMade"
  16. xmlrpc.QueryProtocol.connectionMade(self)
  17. def handleStatus(self, version, status, message):
  18. if debug:
  19. print "version=%s\nstats=%s\nmessage=%s" % (version,status,message)
  20. xmlrpc.QueryProtocol.handleStatus(self,version,status,message)
  21. def handleResponse(self, contents):
  22. if debug:
  23. print "contents=%s" % str(contents)
  24. xmlrpc.QueryProtocol.handleResponse(self, contents)
  25. class AuthQueryFactory(xmlrpc.QueryFactory):
  26. #protocol = xmlrpc.QueryProtocol
  27. protocol = AuthQueryProtocol
  28. def __init__( self, path, host, method, user=None, password=None, *args):
  29. xmlrpc.QueryFactory.__init__(self, path, host, method, user, password, *args)
  30. ## End Comment
  31. class AuthContextFactory(ssl.ClientContextFactory):
  32. def __init__(self, certificate_file_name, private_key_file_name):
  33. self.certificate_file_name = certificate_file_name
  34. self.private_key_file_name = private_key_file_name
  35. def getContext(self):
  36. ctx = SSL.Context(self.method)
  37. ctx.use_certificate_file(self.certificate_file_name)
  38. if self.private_key_file_name:
  39. ctx.use_privatekey_file(self.private_key_file_name)
  40. return ctx
  41. class AuthProxy(xmlrpc.Proxy):
  42. def __init__(self, url, certificate_file_name, private_key_file_name = None,
  43. user=None, password=None):
  44. xmlrpc.Proxy.__init__(self, url, user, password)
  45. self.certificate_file_name = certificate_file_name
  46. self.private_key_file_name = private_key_file_name
  47. def callRemote(self, method, *args):
  48. factory = AuthQueryFactory(self.path, self.host, method,
  49. self.user, self.password, *args)
  50. #factory = xmlrpc.QueryFactory(self.path, self.host, method,
  51. # self.user, self.password, *args)
  52. if self.secure:
  53. from twisted.internet import ssl
  54. #print "Connecting using ssl to host", self.host, "port", (self.port or 443)
  55. reactor.connectSSL(self.host, self.port or 443, factory,
  56. AuthContextFactory(self.certificate_file_name,
  57. self.private_key_file_name))
  58. #reactor.connectSSL(self.host, self.port or 443, factory,
  59. # ssl.DefaultOpenSSLContextFactory("", self.certificate_file_name))
  60. else:
  61. reactor.connectTCP(self.host, self.port or 80, factory)
  62. return factory.deferred