]> xenbits.xensource.com Git - xen.git/commitdiff
Add SSL/TLS support to relocation
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 1 May 2008 08:50:16 +0000 (09:50 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 1 May 2008 08:50:16 +0000 (09:50 +0100)
 * SSL/TLS support is disabled by default, as other server did.

 * If "xend-relocation-server-ssl-key-file" and
   "xend-relocation-server-ssl-cert-file" exist, SSL/TLS is enabled
   automatically.

 * "xend-relocation-tls" is used by relocation client only.

Signed-off-by: Zhigang Wang <zhigang.x.wang@oracle.com>
tools/examples/xend-config.sxp
tools/python/xen/web/tcp.py
tools/python/xen/xend/XendDomain.py
tools/python/xen/xend/XendOptions.py
tools/python/xen/xend/server/relocate.py

index f3ee4f3a15f6247977e4171899b97e42ab9202f8..dc8a209922edc53a854b3a367238d9e3703b0c70 100644 (file)
 # is set.
 #(xend-relocation-port 8002)
 
+# Whether to use tls when relocating.
+#(xend-relocation-tls no)
+
+# SSL key and certificate to use for the relocation interface.
+# Setting these will mean that this port serves only SSL connections as
+# opposed to plaintext ones.
+#(xend-relocation-server-ssl-key-file  /etc/xen/xmlrpc.key)
+#(xend-relocation-server-ssl-cert-file  /etc/xen/xmlrpc.crt)
+
 # Address xend should listen on for HTTP connections, if xend-http-server is
 # set.
 # Specifying 'localhost' prevents remote connections.
index 5ef94db6195ea3a8ceb2be982ebded44daa428c4..f444c208d35d2ff5c4e48c88fec260a225cbc5c2 100644 (file)
@@ -22,6 +22,8 @@ import re
 import socket
 import time
 
+from OpenSSL import SSL
+
 import connection
 
 from xen.xend.XendLogging import log
@@ -64,3 +66,42 @@ class TCPListener(connection.SocketListener):
                 sock.close()
             except:
                 pass
+
+class SSLTCPListener(TCPListener):
+
+    def __init__(self, protocol_class, port, interface, hosts_allow,
+                 ssl_key_file = None, ssl_cert_file = None):
+        if not ssl_key_file or not ssl_cert_file:
+            raise ValueError("SSLXMLRPCServer requires ssl_key_file "
+                             "and ssl_cert_file to be set.")
+
+        self.ssl_key_file = ssl_key_file
+        self.ssl_cert_file = ssl_cert_file
+
+        TCPListener.__init__(self, protocol_class, port, interface, hosts_allow)
+
+
+    def createSocket(self):
+        # make a SSL socket
+        ctx = SSL.Context(SSL.SSLv23_METHOD)
+        ctx.set_options(SSL.OP_NO_SSLv2)
+        ctx.use_privatekey_file (self.ssl_key_file)
+        ctx.use_certificate_file(self.ssl_cert_file)
+        sock = SSL.Connection(ctx,
+                              socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+
+        # SO_REUSEADDR does not always ensure that we do not get an address
+        # in use error when restarted quickly
+        # we implement a timeout to try and avoid failing unnecessarily
+        timeout = time.time() + 30
+        while True:
+            try:
+                sock.bind((self.interface, self.port))
+                return sock
+            except socket.error, (_errno, strerrno):
+                if _errno == errno.EADDRINUSE and time.time() < timeout:
+                    time.sleep(0.5)
+                else:
+                    raise
+
index 81dae6cd30daef6e250300628fd8269a54a78ead..e821329400b4900e9e1d77110f8a82321f3db241 100644 (file)
@@ -1293,8 +1293,16 @@ class XendDomain:
 
         if port == 0:
             port = xoptions.get_xend_relocation_port()
+
         try:
-            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            tls = xoptions.get_xend_relocation_tls()
+            if tls:
+                from OpenSSL import SSL
+                ctx = SSL.Context(SSL.SSLv23_METHOD)
+                sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM))
+                sock.set_connect_state()
+            else:
+                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             sock.connect((dst, port))
         except socket.error, err:
             raise XendError("can't connect: %s" % err[1])
index cae9a4d19a1db03ccf382de57af8e1b59d2eb721..35729af96dd2423f424be6941750a4fd3fd86cb9 100644 (file)
@@ -192,6 +192,12 @@ class XendOptions:
         return self.get_config_bool("xend-relocation-server",
                                     self.xend_relocation_server_default)
 
+    def get_xend_relocation_server_ssl_key_file(self):
+        return self.get_config_string("xend-relocation-server-ssl-key-file")
+
+    def get_xend_relocation_server_ssl_cert_file(self):
+        return self.get_config_string("xend-relocation-server-ssl-cert-file")
+
     def get_xend_port(self):
         """Get the port xend listens at for its HTTP interface.
         """
@@ -203,6 +209,11 @@ class XendOptions:
         return self.get_config_int('xend-relocation-port',
                                    self.xend_relocation_port_default)
 
+    def get_xend_relocation_tls(self):
+        """Whether to use tls when relocating.
+        """
+        return self.get_config_bool('xend-relocation-tls', 'no')
+
     def get_xend_relocation_hosts_allow(self):
         return self.get_config_string("xend-relocation-hosts-allow",
                                      self.xend_relocation_hosts_allow_default)
index 8f6a376bc4a19239254faa798f2e98a126400e72..e71820de20599b7db14a53704b87b1a643b5cec9 100644 (file)
@@ -132,5 +132,14 @@ def listenRelocation():
         else:
             hosts_allow = map(re.compile, hosts_allow.split(" "))
 
-        tcp.TCPListener(RelocationProtocol, port, interface = interface,
-                        hosts_allow = hosts_allow)
+        ssl_key_file = xoptions.get_xend_relocation_server_ssl_key_file()
+        ssl_cert_file = xoptions.get_xend_relocation_server_ssl_cert_file()
+
+        if ssl_key_file and ssl_cert_file:
+            tcp.SSLTCPListener(RelocationProtocol, port, interface = interface,
+                               hosts_allow = hosts_allow,
+                               ssl_key_file = ssl_key_file,
+                               ssl_cert_file = ssl_cert_file)
+        else:
+            tcp.TCPListener(RelocationProtocol, port, interface = interface,
+                            hosts_allow = hosts_allow)