WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Implement an "allowed hosts" mechanism fo

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Implement an "allowed hosts" mechanism for the XML-RPC server layer, using
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 28 Nov 2006 13:40:32 +0000
Delivery-date: Tue, 28 Nov 2006 05:42:11 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Node ID 6206685650f582d79f4b84f2b4d35d886cccdff0
# Parent  b4baf35cff112b60c5f7d077e2c23d97e9480cf8
Implement an "allowed hosts" mechanism for the XML-RPC server layer, using
code from the relocation protocol handling and some plumbing.  Add a new
configuration entry for the Xen-API server, including use of this mechanism.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
---
 tools/examples/xend-config.sxp               |   26 ++++++++++++++++++++++++++
 tools/python/xen/util/xmlrpclib2.py          |   27 ++++++++++++++++++++++-----
 tools/python/xen/web/connection.py           |   16 +++++++++++++++-
 tools/python/xen/web/tcp.py                  |   14 ++------------
 tools/python/xen/xend/XendRoot.py            |    9 +++++++++
 tools/python/xen/xend/server/SrvServer.py    |   24 ++++++++++++++++++++++++
 tools/python/xen/xend/server/XMLRPCServer.py |   13 +++++++++++--
 7 files changed, 109 insertions(+), 20 deletions(-)

diff -r b4baf35cff11 -r 6206685650f5 tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp    Tue Nov 28 09:51:05 2006 +0000
+++ b/tools/examples/xend-config.sxp    Tue Nov 28 10:23:34 2006 +0000
@@ -13,6 +13,32 @@
 
 #(logfile /var/log/xen/xend.log)
 #(loglevel DEBUG)
+
+# The Xen-API server configuration.  (Please note that this server is available
+# as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied upon).
+#
+# This value configures the ports, interfaces, and access controls for the
+# Xen-API server.  Each entry in the list starts with either unix, a port
+# number, or an address:port pair.  If this is "unix", then a UDP socket is
+# opened, and this entry applies to that.  If it is a port, then Xend will
+# listen on all interfaces on that TCP port, and if it is an address:port pair,
+# then Xend will listen on the specified port, using the interface with the
+# specified address.
+#
+# The subsequent string gives the access control for the listener in question. 
+# If this is missing or empty, then all connections are accepted.
+# Otherwise, this should be a space-separated sequence of regular expressions;
+# any host with a fully-qualified domain name or an IP address that matches one
+# of these regular expressions will be accepted.
+#
+# Example:
+#
+#  Listen on TCP port 9363 on all interfaces, accepting connections only from
+#  machines in example.com or localhost.
+#  (xen-api-server ((9363 '^localhost$ example\\.com$')))
+#
+# Default:
+#   (xen-api-server ((unix)))
 
 #(xend-http-server no)
 #(xend-unix-server no)
diff -r b4baf35cff11 -r 6206685650f5 tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py       Tue Nov 28 09:51:05 2006 +0000
+++ b/tools/python/xen/util/xmlrpclib2.py       Tue Nov 28 10:23:34 2006 +0000
@@ -30,6 +30,7 @@ import SocketServer
 import SocketServer
 import xmlrpclib, socket, os, stat
 
+from xen.web import connection
 from xen.xend.XendLogging import log
 
 try:
@@ -70,6 +71,11 @@ class XMLRPCRequestHandler(SimpleXMLRPCR
 class XMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
     protocol_version = "HTTP/1.1"
 
+    def __init__(self, hosts_allowed, request, client_address, server):
+        self.hosts_allowed = hosts_allowed
+        SimpleXMLRPCRequestHandler.__init__(self, request, client_address,
+                                            server)
+
     # this is inspired by SimpleXMLRPCRequestHandler's do_POST but differs
     # in a few non-trivial ways
     # 1) we never generate internal server errors.  We let the exception
@@ -77,6 +83,11 @@ class XMLRPCRequestHandler(SimpleXMLRPCR
     # 2) we don't bother checking for a _dispatch function since we don't
     #    use one
     def do_POST(self):
+        addrport = self.client_address
+        if not connection.hostAllowed(addrport, self.hosts_allowed):
+            self.connection.shutdown(1)
+            return
+
         data = self.rfile.read(int(self.headers["content-length"]))
         rsp = self.server._marshaled_dispatch(data)
 
@@ -150,9 +161,14 @@ class TCPXMLRPCServer(SocketServer.Threa
 class TCPXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer):
     allow_reuse_address = True
 
-    def __init__(self, addr, requestHandler=XMLRPCRequestHandler,
+    def __init__(self, addr, allowed, requestHandler=None,
                  logRequests = 1):
-        SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests)
+        if requestHandler is None:
+            requestHandler = XMLRPCRequestHandler
+        SimpleXMLRPCServer.__init__(self, addr,
+                                    (lambda x, y, z:
+                                     requestHandler(allowed, x, y, z)),
+                                    logRequests)
 
         flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
         flags |= fcntl.FD_CLOEXEC
@@ -217,7 +233,7 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
 class UnixXMLRPCServer(TCPXMLRPCServer):
     address_family = socket.AF_UNIX
 
-    def __init__(self, addr, logRequests = 1):
+    def __init__(self, addr, allowed, logRequests = 1):
         parent = os.path.dirname(addr)
         if os.path.exists(parent):
             os.chown(parent, os.geteuid(), os.getegid())
@@ -226,5 +242,6 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
                 os.unlink(addr)
         else:
             os.makedirs(parent, stat.S_IRWXU)
-        TCPXMLRPCServer.__init__(self, addr, UnixXMLRPCRequestHandler,
-                                 logRequests)
+
+        TCPXMLRPCServer.__init__(self, addr, allowed,
+                                 UnixXMLRPCRequestHandler, logRequests)
diff -r b4baf35cff11 -r 6206685650f5 tools/python/xen/web/connection.py
--- a/tools/python/xen/web/connection.py        Tue Nov 28 09:51:05 2006 +0000
+++ b/tools/python/xen/web/connection.py        Tue Nov 28 10:23:34 2006 +0000
@@ -24,6 +24,8 @@ import fcntl
 
 from errno import EAGAIN, EINTR, EWOULDBLOCK
 
+from xen.xend.XendLogging import log
+
 """General classes to support server and client sockets, without
 specifying what kind of socket they are. There are subclasses
 for TCP and unix-domain sockets (see tcp.py and unix.py).
@@ -76,7 +78,7 @@ class SocketListener:
     Accepts connections and runs a thread for each one.
     """
 
-    def __init__(self, protocol_class, hosts_allow = ''):
+    def __init__(self, protocol_class):
         self.protocol_class = protocol_class
         self.sock = self.createSocket()
         threading.Thread(target=self.main).start()
@@ -111,3 +113,15 @@ class SocketListener:
                         break
         finally:
             self.close()
+
+
+def hostAllowed(addrport, hosts_allowed):
+    if hosts_allowed is None:
+        return True
+    else:
+        fqdn = socket.getfqdn(addrport[0])
+        for h in hosts_allowed:
+            if h.match(fqdn) or h.match(addrport[0]):
+                return True
+        log.warn("Rejected connection from %s (%s).", addrport[0], fqdn)
+        return False
diff -r b4baf35cff11 -r 6206685650f5 tools/python/xen/web/tcp.py
--- a/tools/python/xen/web/tcp.py       Tue Nov 28 09:51:05 2006 +0000
+++ b/tools/python/xen/web/tcp.py       Tue Nov 28 10:23:34 2006 +0000
@@ -57,20 +57,10 @@ class TCPListener(connection.SocketListe
 
     def acceptConnection(self, sock, addrport):
         addr = addrport[0]
-        if self.hosts_allow is None:
-                connection.SocketServerConnection(sock, self.protocol_class)
+        if connection.hostAllowed(addrport, self.hosts_allow):
+            connection.SocketServerConnection(sock, self.protocol_class)
         else:
-            fqdn = socket.getfqdn(addr)
-            for h in self.hosts_allow:
-                if h.match(fqdn) or h.match(addr):
-                    log.debug("Match %s %s", fqdn, h.pattern)
-                    connection.SocketServerConnection(sock,
-                                                      self.protocol_class)
-                    return
-
             try:
-                log.warn("Rejected connection from %s:%d (%s) for port %d.",
-                         addr, addrport[1], fqdn, self.port)
                 sock.close()
             except:
                 pass
diff -r b4baf35cff11 -r 6206685650f5 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Tue Nov 28 09:51:05 2006 +0000
+++ b/tools/python/xen/xend/XendRoot.py Tue Nov 28 10:23:34 2006 +0000
@@ -53,6 +53,9 @@ class XendRoot:
 
     """Default level of information to be logged."""
     loglevel_default = 'DEBUG'
+
+    """Default Xen-API server configuration. """
+    xen_api_server_default = [['unix']]
 
     """Default for the flag indicating whether xend should run an http server
     (deprecated)."""
@@ -189,6 +192,12 @@ class XendRoot:
         except Exception:
             raise XendError("invalid xend config %s: expected int: %s" % 
(name, v))
 
+    def get_xen_api_server(self):
+        """Get the Xen-API server configuration.
+        """
+        return self.get_config_value('xen-api-server',
+                                     self.xen_api_server_default)
+
     def get_xend_http_server(self):
         """Get the flag indicating whether xend should run an http server.
         """
diff -r b4baf35cff11 -r 6206685650f5 tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Tue Nov 28 09:51:05 2006 +0000
+++ b/tools/python/xen/xend/server/SrvServer.py Tue Nov 28 10:23:34 2006 +0000
@@ -41,6 +41,7 @@
 # todo Support command-line args.
 
 import fcntl
+import re
 import time
 import signal
 from threading import Thread
@@ -148,6 +149,29 @@ def create():
         log.info('unix path=' + path)
         servers.add(UnixHttpServer(root, path))
 
+    api_cfg = xroot.get_xen_api_server()
+    if api_cfg:
+        try:
+            addrs = [(str(x[0]).split(':'),
+                      len(x) > 1 and x[1] and map(re.compile, x[1].split(" "))
+                      or None)
+                     for x in api_cfg]
+            for addrport, allowed in addrs:
+                if len(addrport) == 1:
+                    if addrport[0] == 'unix':
+                        servers.add(XMLRPCServer(allowed = allowed))
+                    else:
+                        servers.add(XMLRPCServer(True, '', int(addrport[0]),
+                                                 allowed = allowed))
+                else:
+                    addr, port = addrport
+                    servers.add(XMLRPCServer(True, addr, int(port),
+                                             allowed = allowed))
+        except ValueError:
+            log.error('Xen-API server configuration %s is invalid' % api_cfg)
+        except TypeError:
+            log.error('Xen-API server configuration %s is invalid' % api_cfg)
+
     if xroot.get_xend_tcp_xmlrpc_server():
         servers.add(XMLRPCServer(True))
 
diff -r b4baf35cff11 -r 6206685650f5 
tools/python/xen/xend/server/XMLRPCServer.py
--- a/tools/python/xen/xend/server/XMLRPCServer.py      Tue Nov 28 09:51:05 
2006 +0000
+++ b/tools/python/xen/xend/server/XMLRPCServer.py      Tue Nov 28 10:23:34 
2006 +0000
@@ -85,11 +85,12 @@ exclude = ['domain_create', 'domain_rest
 
 class XMLRPCServer:
     def __init__(self, use_tcp=False, host = "localhost", port = 8006,
-                 path = XML_RPC_SOCKET):
+                 path = XML_RPC_SOCKET, hosts_allowed = None):
         self.use_tcp = use_tcp
         self.port = port
         self.host = host
         self.path = path
+        self.hosts_allowed = hosts_allowed
         
         self.ready = False        
         self.running = True
@@ -97,10 +98,18 @@ class XMLRPCServer:
         
     def run(self):
         if self.use_tcp:
+            log.info("Opening TCP XML-RPC server on %s%d.",
+                     self.host and '%s:' % self.host or
+                     'all interfaces, port ',
+                     self.port)
             self.server = TCPXMLRPCServer((self.host, self.port),
+                                          self.hosts_allowed,
                                           logRequests = False)
         else:
-            self.server = UnixXMLRPCServer(self.path, logRequests = False)
+            log.info("Opening Unix domain socket XML-RPC server on %s:%d.",
+                     self.path)
+            self.server = UnixXMLRPCServer(self.path, self.hosts_allowed,
+                                           logRequests = False)
 
         # Register Xen API Functions
         # -------------------------------------------------------------------

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Implement an "allowed hosts" mechanism for the XML-RPC server layer, using, Xen patchbot-unstable <=