ia64/xen-unstable

changeset 9229:faa1eb1621b9

Simplify the interface into httpserver and UnixHttpServer -- the root and
interface parameters are always used, so there's no need for them to be named
parameters with defaults.

Remove unused httpserver.getRoot and getPort, and simplify the main request
loop. This means that socket errors do not have to be squelched.

Coalesce the two identical bind methods, one in UnixHttpServer, one in
UnixListener. Fix this bind method to set the permissions on the socket
explicitly. This closes a security hole, and fixes the intermittent failure
of xm-test/06_list_nonroot.test.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@leeni.uk.xensource.com
date Fri Mar 10 11:44:03 2006 +0100 (2006-03-10)
parents 83a882b3d807
children 9dbc0786b502
files tools/python/xen/web/httpserver.py tools/python/xen/web/unix.py tools/python/xen/xend/server/SrvServer.py
line diff
     1.1 --- a/tools/python/xen/web/httpserver.py	Fri Mar 10 11:38:15 2006 +0100
     1.2 +++ b/tools/python/xen/web/httpserver.py	Fri Mar 10 11:44:03 2006 +0100
     1.3 @@ -13,7 +13,9 @@
     1.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     1.5  #============================================================================
     1.6  # Copyright (C) 2005 Mike Wray <mike.wray@hp.com>
     1.7 +# Copyright (C) 2006 XenSource Ltd.
     1.8  #============================================================================
     1.9 +
    1.10  import threading
    1.11  
    1.12  import string
    1.13 @@ -28,6 +30,7 @@ from xen.xend.Args import ArgError
    1.14  from xen.xend.XendError import XendError
    1.15  
    1.16  import http
    1.17 +import unix
    1.18  from resource import Resource, ErrorPage
    1.19  from SrvDir import SrvDir
    1.20  
    1.21 @@ -267,31 +270,28 @@ class HttpServer:
    1.22  
    1.23      closed = False
    1.24  
    1.25 -    def __init__(self, interface='', port=8080, root=None):
    1.26 -        if root is None:
    1.27 -            root = SrvDir()
    1.28 +    def __init__(self, root, interface, port=8080):
    1.29 +        self.root = root
    1.30          self.interface = interface
    1.31          self.port = port
    1.32 -        self.root = root
    1.33          # ready indicates when we are ready to begin accept connections
    1.34          # it should be set after a successful bind
    1.35          self.ready = False
    1.36  
    1.37 -    def getRoot(self):
    1.38 -        return self.root
    1.39 -
    1.40 -    def getPort(self):
    1.41 -        return self.port
    1.42 -
    1.43      def run(self):
    1.44          self.bind()
    1.45          self.listen()
    1.46          self.ready = True
    1.47 -        self.requestLoop()
    1.48 +
    1.49 +        while not self.closed:
    1.50 +            (sock, addr) = self.accept()
    1.51 +            self.processRequest(sock, addr)
    1.52 +
    1.53  
    1.54      def stop(self):
    1.55          self.close()
    1.56  
    1.57 +
    1.58      def bind(self):
    1.59          self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    1.60          self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    1.61 @@ -303,10 +303,6 @@ class HttpServer:
    1.62      def accept(self):
    1.63          return self.socket.accept()
    1.64  
    1.65 -    def requestLoop(self):
    1.66 -        while not self.closed:
    1.67 -            self.acceptRequest()
    1.68 -
    1.69      def close(self):
    1.70          self.closed = True
    1.71          try:
    1.72 @@ -314,13 +310,6 @@ class HttpServer:
    1.73          except:
    1.74              pass
    1.75  
    1.76 -    def acceptRequest(self):
    1.77 -        try:
    1.78 -            (sock, addr) = self.accept()
    1.79 -            self.processRequest(sock, addr)
    1.80 -        except socket.error:
    1.81 -            return
    1.82 -
    1.83      def processRequest(self, sock, addr):
    1.84          try:
    1.85              rp = RequestProcessor(self, sock, addr)
    1.86 @@ -340,23 +329,12 @@ class HttpServer:
    1.87      def getResource(self, req):
    1.88          return self.root.getRequestResource(req)
    1.89  
    1.90 +
    1.91  class UnixHttpServer(HttpServer):
    1.92  
    1.93 -    def __init__(self, path=None, root=None):
    1.94 -        HttpServer.__init__(self, interface='localhost', root=root)
    1.95 +    def __init__(self, root, path):
    1.96 +        HttpServer.__init__(self, root, 'localhost')
    1.97          self.path = path
    1.98          
    1.99      def bind(self):
   1.100 -        pathdir = os.path.dirname(self.path)
   1.101 -        if not os.path.exists(pathdir):
   1.102 -            os.makedirs(pathdir)
   1.103 -        else:
   1.104 -            try:
   1.105 -                os.unlink(self.path)
   1.106 -            except SystemExit:
   1.107 -                raise
   1.108 -            except Exception, ex:
   1.109 -                pass
   1.110 -        self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   1.111 -        #self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
   1.112 -        self.socket.bind(self.path)
   1.113 +        self.socket = unix.bind(self.path)
     2.1 --- a/tools/python/xen/web/unix.py	Fri Mar 10 11:38:15 2006 +0100
     2.2 +++ b/tools/python/xen/web/unix.py	Fri Mar 10 11:44:03 2006 +0100
     2.3 @@ -13,17 +13,36 @@
     2.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     2.5  #============================================================================
     2.6  # Copyright (C) 2005 Mike Wray <mike.wray@hp.com>
     2.7 -# Copyright (C) 2005 XenSource Ltd.
     2.8 +# Copyright (C) 2005-2006 XenSource Ltd.
     2.9  #============================================================================
    2.10  
    2.11  
    2.12 -import socket
    2.13  import os
    2.14  import os.path
    2.15 +import socket
    2.16 +import stat
    2.17  
    2.18  import connection
    2.19  
    2.20  
    2.21 +def bind(path):
    2.22 +    """Create a Unix socket, and bind it to the given path.  The socket is
    2.23 +created such that only the current user may access it."""
    2.24 +
    2.25 +    parent = os.path.dirname(path)
    2.26 +    if os.path.exists(parent):
    2.27 +        os.chown(parent, os.geteuid(), os.getegid())
    2.28 +        os.chmod(parent, stat.S_IRWXU)
    2.29 +        if os.path.exists(path):
    2.30 +            os.unlink(path)
    2.31 +    else:
    2.32 +        os.makedirs(parent, stat.S_IRWXU)
    2.33 +
    2.34 +    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    2.35 +    sock.bind(self.path)
    2.36 +    return sock
    2.37 +
    2.38 +
    2.39  class UnixListener(connection.SocketListener):
    2.40      def __init__(self, path, protocol_class):
    2.41          self.path = path
    2.42 @@ -31,19 +50,7 @@ class UnixListener(connection.SocketList
    2.43  
    2.44  
    2.45      def createSocket(self):
    2.46 -        pathdir = os.path.dirname(self.path)
    2.47 -        if not os.path.exists(pathdir):
    2.48 -            os.makedirs(pathdir)
    2.49 -        else:
    2.50 -            try:
    2.51 -                os.unlink(self.path)
    2.52 -            except SystemExit:
    2.53 -                raise
    2.54 -            except Exception, ex:
    2.55 -                pass
    2.56 -        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    2.57 -        sock.bind(self.path)
    2.58 -        return sock
    2.59 +        return bind(self.path)
    2.60  
    2.61  
    2.62      def acceptConnection(self, sock, _):
     3.1 --- a/tools/python/xen/xend/server/SrvServer.py	Fri Mar 10 11:38:15 2006 +0100
     3.2 +++ b/tools/python/xen/xend/server/SrvServer.py	Fri Mar 10 11:44:03 2006 +0100
     3.3 @@ -13,6 +13,7 @@
     3.4  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     3.5  #============================================================================
     3.6  # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
     3.7 +# Copyright (C) 2006 XenSource Ltd.
     3.8  #============================================================================
     3.9  
    3.10  """Example xend HTTP
    3.11 @@ -106,11 +107,11 @@ def create():
    3.12      root.putChild('xend', SrvRoot())
    3.13      servers = XendServers()
    3.14      if xroot.get_xend_http_server():
    3.15 -        port = xroot.get_xend_port()
    3.16 -        interface = xroot.get_xend_address()
    3.17 -        servers.add(HttpServer(root=root, interface=interface, port=port))
    3.18 +        servers.add(HttpServer(root,
    3.19 +                               xroot.get_xend_address(),
    3.20 +                               xroot.get_xend_port()))
    3.21      if xroot.get_xend_unix_server():
    3.22          path = xroot.get_xend_unix_path()
    3.23          log.info('unix path=' + path)
    3.24 -        servers.add(UnixHttpServer(path=path, root=root))
    3.25 +        servers.add(UnixHttpServer(root, path))
    3.26      return servers