1
#============================================================================
2
# This library is free software; you can redistribute it and/or
3
# modify it under the terms of version 2.1 of the GNU Lesser General Public
4
# License as published by the Free Software Foundation.
6
# This library is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
# Lesser General Public License for more details.
11
# You should have received a copy of the GNU Lesser General Public
12
# License along with this library; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14
#============================================================================
15
# Copyright (C) 2007 XenSource Inc.
16
#============================================================================
20
HTTPS wrapper for an XML-RPC server interface. Requires PyOpenSSL (Debian
21
package python-pyopenssl).
26
from OpenSSL import SSL
28
from xen.util.xmlrpclib2 import XMLRPCRequestHandler, TCPXMLRPCServer
31
class SSLXMLRPCRequestHandler(XMLRPCRequestHandler):
33
self.connection = self.request
34
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
35
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
38
# Taken from pyOpenSSL-0.6 examples (public-domain)
44
def __init__(self, conn):
46
Connection is not yet a new-style class,
47
so I'm making a proxy instead of subclassing.
49
self.__dict__["conn"] = conn
50
def __getattr__(self, name):
51
return getattr(self.__dict__["conn"], name)
52
def __setattr__(self, name, value):
53
setattr(self.__dict__["conn"], name, value)
57
return self.__dict__["conn"].close()
59
def shutdown(self, how=1):
61
SimpleXMLRpcServer.doPOST calls shutdown(1),
62
and Connection.shutdown() doesn't take
63
an argument. So we just discard the argument.
65
# Block until the shutdown is complete
66
self.__dict__["conn"].shutdown()
67
self.__dict__["conn"].shutdown()
71
This is the other part of the shutdown() workaround.
72
Since servers create new sockets, we have to infect
73
them with our magic. :)
75
c, a = self.__dict__["conn"].accept()
76
return (SSLWrapper(c), a)
79
# End of pyOpenSSL-0.6 example code.
82
class SSLXMLRPCServer(TCPXMLRPCServer):
83
def __init__(self, addr, allowed, xenapi, logRequests = 1,
84
ssl_key_file = None, ssl_cert_file = None):
86
TCPXMLRPCServer.__init__(self, addr, allowed, xenapi,
87
SSLXMLRPCRequestHandler, logRequests)
89
if not ssl_key_file or not ssl_cert_file:
90
raise ValueError("SSLXMLRPCServer requires ssl_key_file "
91
"and ssl_cert_file to be set.")
94
ctx = SSL.Context(SSL.SSLv23_METHOD)
95
ctx.set_options(SSL.OP_NO_SSLv2)
96
ctx.use_privatekey_file (ssl_key_file)
97
ctx.use_certificate_file(ssl_cert_file)
98
self.socket = SSLWrapper(SSL.Connection(ctx,
99
socket.socket(self.address_family,
101
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
103
self.server_activate()