modifs à la gateway pour qu'elle fasse serveur xml-rpc/ssl avec pyopenssl
plutôt que m2crypto
This commit is contained in:
parent
a86839e432
commit
32b271b35d
|
@ -53,7 +53,7 @@ import sys
|
|||
import traceback
|
||||
|
||||
try:
|
||||
from M2Crypto import SSL
|
||||
from OpenSSL import SSL
|
||||
except ImportError:
|
||||
SSL = None
|
||||
|
||||
|
@ -223,23 +223,19 @@ class Gateway(applications.Application):
|
|||
|
||||
def startRpcServer(self):
|
||||
if SSL:
|
||||
from glasnost.server.xmlrpcServer import XmlRpcSslThreadingServer
|
||||
from glasnost.server.xmlrpcServer import SecureXmlRpcThreadingServer
|
||||
|
||||
certificatePath = '/etc/%s/server.pem' % glasnost.applicationName
|
||||
certificateAutorityPath = '/etc/%s/ca.pem' \
|
||||
% glasnost.applicationName
|
||||
verifyDepth = 10
|
||||
sslContext = SSL.Context('sslv2')
|
||||
sslContext.load_cert(certificatePath)
|
||||
sslContext.load_client_ca(certificateAutorityPath)
|
||||
sslContext.load_verify_info(certificateAutorityPath)
|
||||
sslContext.set_verify(SSL.verify_none, verifyDepth)
|
||||
sslContext.set_allow_unknown_ca(1)
|
||||
sslContext.set_session_id_ctx('xmlrpc')
|
||||
sslContext.set_info_callback()
|
||||
|
||||
self.rpcServer = XmlRpcSslThreadingServer(
|
||||
('', self.port), sslContext = sslContext)
|
||||
ctx = SSL.Context(SSL.SSLv23_METHOD)
|
||||
ctx.set_options(SSL.OP_NO_SSLv2)
|
||||
ctx.use_privatekey_file ('/etc/%s/server.pkey' % glasnost.applicationName)
|
||||
ctx.use_certificate_file('/etc/%s/server.cert' % glasnost.applicationName)
|
||||
|
||||
self.rpcServer = SecureXmlRpcThreadingServer(
|
||||
('', self.port), sslContext = ctx)
|
||||
else:
|
||||
from glasnost.server.xmlrpcServer import XmlRpcThreadingServer
|
||||
self.rpcServer = XmlRpcThreadingServer(('', self.port))
|
||||
|
|
|
@ -80,6 +80,8 @@
|
|||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
|
||||
# This files also contains code derived from SecureXMLRPCServer.py by Michal
|
||||
# Wallace and distributed with pyopenssl (and placed in the public domain).
|
||||
|
||||
__version__ = '$Revision$'[11:-2]
|
||||
|
||||
|
@ -97,7 +99,7 @@ import traceback
|
|||
import xmlrpclib
|
||||
|
||||
try:
|
||||
from M2Crypto import SSL
|
||||
from OpenSSL import SSL
|
||||
except ImportError:
|
||||
SSL = None
|
||||
|
||||
|
@ -489,23 +491,11 @@ class FastThreadingServer(SocketServer.ThreadingMixIn, FastServer):
|
|||
|
||||
class XmlRpcServer(ServerMixin, SocketServer.TCPServer):
|
||||
__server_version = 'XmlRpcServer/' + __version__
|
||||
allow_reuse_address = 1
|
||||
|
||||
def __init__(self, serverAddress):
|
||||
# Try five time to obtain the socket.
|
||||
i = 0
|
||||
while 1:
|
||||
try:
|
||||
SocketServer.TCPServer.__init__(self, serverAddress,
|
||||
XmlRpcRequestHandler)
|
||||
break
|
||||
except socket.error, e:
|
||||
if e.args[0] == 98:
|
||||
i += 1
|
||||
if i == 5:
|
||||
raise
|
||||
time.sleep(2)
|
||||
continue
|
||||
raise
|
||||
SocketServer.TCPServer.__init__(self, serverAddress,
|
||||
XmlRpcRequestHandler)
|
||||
|
||||
if serverAddress[0] == '':
|
||||
host = socket.gethostbyaddr(socket.gethostname())[0]
|
||||
|
@ -531,25 +521,72 @@ class XmlRpcForkingServer(SocketServer.ForkingMixIn, XmlRpcServer):
|
|||
|
||||
|
||||
if SSL:
|
||||
class XmlRpcSslServer(ServerMixin, SSL.SSLServer):
|
||||
__server_version = 'XmlRpcSslServer/' + __version__
|
||||
class SSLBugFix:
|
||||
"""
|
||||
SSL Connection tends to die on sendall,
|
||||
so I use send() as a workaround. This is
|
||||
called by socket._fileobject, which is needed
|
||||
so SocketServer (and kids) can treat the connection
|
||||
as a regular file.
|
||||
"""
|
||||
def __init__(self, conn):
|
||||
"""
|
||||
For some reason, I can't subclass Connection,
|
||||
so I'm making a proxy, instead.
|
||||
"""
|
||||
self.__dict__["conn"] = conn
|
||||
def __getattr__(self,name):
|
||||
return getattr(self.__dict__["conn"], name)
|
||||
def __setattr__(self,name, value):
|
||||
setattr(self.__dict__["conn"], name, value)
|
||||
|
||||
|
||||
def sendall(self, data):
|
||||
"""
|
||||
This is the bugfix. Connection.sendall() segfaults
|
||||
on socket._fileobject.flush(), so just rewire it
|
||||
to use send() instead.
|
||||
"""
|
||||
self.__dict__["conn"].send(data)
|
||||
|
||||
def shutdown(self, how=1):
|
||||
"""
|
||||
This isn't part of the bugfix. SimpleXMLRpcServer.doPOST
|
||||
calls shutdown(1), and Connection.shutdown() doesn't take
|
||||
an argument. So we just discard it:
|
||||
"""
|
||||
self.__dict__["conn"].shutdown()
|
||||
|
||||
def accept(self):
|
||||
"""
|
||||
This is the other part of the shutdown() workaround.
|
||||
Since servers create new sockets, we have to infect
|
||||
them with our magic. :)
|
||||
"""
|
||||
c, a = self.__dict__["conn"].accept()
|
||||
return (SSLBugFix(c), a)
|
||||
|
||||
|
||||
|
||||
class SecureTCPServer(SocketServer.TCPServer):
|
||||
"""
|
||||
Just like TCPServer, but use a socket.
|
||||
This really ought to let you specify the key and certificate files.
|
||||
"""
|
||||
def __init__(self, server_address, sslContext, RequestHandlerClass):
|
||||
SocketServer.BaseServer.__init__(self, server_address, RequestHandlerClass)
|
||||
|
||||
self.socket = SSLBugFix(SSL.Connection(sslContext,
|
||||
socket.socket(self.address_family, self.socket_type)))
|
||||
self.server_bind()
|
||||
self.server_activate()
|
||||
|
||||
class SecureXmlRpcServer(ServerMixin, SecureTCPServer):
|
||||
__server_version = 'SecureXmlRpcServer/' + __version__
|
||||
|
||||
def __init__(self, serverAddress, sslContext):
|
||||
# Try five time to obtain the socket.
|
||||
i = 0
|
||||
while 1:
|
||||
try:
|
||||
SSL.SSLServer.__init__(self, serverAddress,
|
||||
XmlRpcRequestHandler, sslContext)
|
||||
break
|
||||
except socket.error, e:
|
||||
if e.args[0] == 98:
|
||||
i += 1
|
||||
if i == 5:
|
||||
raise
|
||||
time.sleep(2)
|
||||
continue
|
||||
raise
|
||||
SecureTCPServer.__init__(self, serverAddress, sslContext,
|
||||
SecureXmlRpcRequestHandler)
|
||||
|
||||
if serverAddress[0] == '':
|
||||
host = socket.gethostbyaddr(socket.gethostname())[0]
|
||||
|
@ -559,25 +596,17 @@ if SSL:
|
|||
|
||||
ServerMixin.__init__(self)
|
||||
|
||||
def finish(self):
|
||||
print 'Finishing request'
|
||||
self.request.set_shutdown(
|
||||
SSL.SSL_RECEIVED_SHUTDOWN | SSL.SSL_SENT_SHUTDOWN)
|
||||
print 'Almost done'
|
||||
self.request.close()
|
||||
print 'Done'
|
||||
|
||||
def serve_forever(self):
|
||||
self.log_message('Awaiting XML-RPC SSL connections')
|
||||
SSL.SSLServer.serve_forever(self)
|
||||
self.log_message('Finished serving XML-RPC SSL connections')
|
||||
self.log_message('Awaiting XML-RPC/SSL connections')
|
||||
SecureTCPServer.serve_forever(self)
|
||||
self.log_message('Finished serving XML-RPC/SSL connections')
|
||||
|
||||
|
||||
class XmlRpcSslThreadingServer(SocketServer.ThreadingMixIn, XmlRpcSslServer):
|
||||
class SecureXmlRpcThreadingServer(SocketServer.ThreadingMixIn, SecureXmlRpcServer):
|
||||
pass
|
||||
|
||||
|
||||
class XmlRpcSslForkingServer(SocketServer.ForkingMixIn, XmlRpcSslServer):
|
||||
class SecureXmlRpcForkingServer(SocketServer.ForkingMixIn, SecureXmlRpcServer):
|
||||
pass
|
||||
|
||||
|
||||
|
@ -664,3 +693,15 @@ class XmlRpcRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
self.wfile.flush()
|
||||
self.connection.shutdown(1)
|
||||
|
||||
|
||||
class SecureXmlRpcRequestHandler(XmlRpcRequestHandler):
|
||||
def setup(self):
|
||||
"""
|
||||
We need to use socket._fileobject Because SSL.Connection
|
||||
doesn't have a 'dup'. Not exactly sure WHY this is, but
|
||||
this is backed up by comments in socket.py and SSL/connection.c
|
||||
"""
|
||||
self.connection = self.request # for doPOST
|
||||
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
|
||||
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
|
||||
|
||||
|
|
Reference in New Issue