# HG changeset patch
# User emellor@xxxxxxxxxxxxxxxxxxxxxx
# Node ID 58397be18c524eeb3af0352472e808f2987d810e
# Parent 566395e5a14fd914b3f38c3ed7b6b019a1bcdae3
Added a hosts-allow facility to TCP connections, which allows us to restrict
the acceptable connections based upon a regular expression comparison with the
FQDN or the IP address.
Use the hosts-allow facility to restrict access to the relocation socket. This
adds the configuration option xend-relocation-hosts-allow, which takes a
space-separated sequence of regular expressions.
Pass the protocol class instance through to SocketServerConnection, rather than
a new instance of that class. This means that the new instance need not be
passed through SocketListener.acceptConnection.
Make the SocketServerConnection and SocketListener classes start their
corresponding threads and open their sockets (in the case of SocketListener)
automatically. This means that callers do not need to save an instance locally,
just to call run() or listen() on it. This also means that listenTCP and
listenUnix can go -- simply creating a TCPListener or UnixListener instance is
sufficient.
Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
diff -r 566395e5a14f -r 58397be18c52 tools/python/xen/web/connection.py
--- a/tools/python/xen/web/connection.py Mon Dec 12 16:32:50 2005
+++ b/tools/python/xen/web/connection.py Mon Dec 12 16:43:48 2005
@@ -19,7 +19,6 @@
import sys
import threading
-import select
import socket
import fcntl
@@ -31,21 +30,17 @@
"""
BUFFER_SIZE = 1024
+BACKLOG = 5
class SocketServerConnection:
"""An accepted connection to a server.
"""
- def __init__(self, sock, protocol, addr, server):
+ def __init__(self, sock, protocol_class):
self.sock = sock
- self.protocol = protocol
- self.addr = addr
- self.server = server
+ self.protocol = protocol_class()
self.protocol.setTransport(self)
-
-
- def run(self):
threading.Thread(target=self.main).start()
@@ -68,6 +63,10 @@
pass
+ def close(self):
+ self.sock.close()
+
+
def write(self, data):
self.sock.send(data)
@@ -77,52 +76,38 @@
Accepts connections and runs a thread for each one.
"""
- def __init__(self, protocol_class, backlog=None):
- if backlog is None:
- backlog = 5
+ def __init__(self, protocol_class, hosts_allow = ''):
self.protocol_class = protocol_class
- self.sock = None
- self.backlog = backlog
- self.thread = None
+ self.sock = self.createSocket()
+ threading.Thread(target=self.main).start()
+
+
+ def close(self):
+ try:
+ self.sock.close()
+ except:
+ pass
def createSocket(self):
raise NotImplementedError()
- def setCloExec(self):
- fcntl.fcntl(self.sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
-
-
def acceptConnection(self, sock, protocol, addr):
- return SocketServerConnection(sock, protocol, addr, self)
-
-
- def listen(self):
- if self.sock or self.thread:
- raise IOError("already listening")
- self.sock = self.createSocket()
- self.sock.listen(self.backlog)
- self.run()
-
-
- def run(self):
- self.thread = threading.Thread(target=self.main)
- self.thread.start()
+ raise NotImplementedError()
def main(self):
try:
+ fcntl.fcntl(self.sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC)
+ self.sock.listen(BACKLOG)
+
while True:
try:
(sock, addr) = self.sock.accept()
- self.acceptConnection(sock, self.protocol_class(),
- addr).run()
+ self.acceptConnection(sock, addr)
except socket.error, ex:
if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR):
break
finally:
- try:
- self.sock.close()
- except:
- pass
+ self.close()
diff -r 566395e5a14f -r 58397be18c52 tools/python/xen/web/tcp.py
--- a/tools/python/xen/web/tcp.py Mon Dec 12 16:32:50 2005
+++ b/tools/python/xen/web/tcp.py Mon Dec 12 16:43:48 2005
@@ -17,20 +17,25 @@
#============================================================================
+import errno
+import re
import socket
import time
-import errno
-from connection import *
+import connection
+
+from xen.xend.XendLogging import log
-class TCPListener(SocketListener):
+class TCPListener(connection.SocketListener):
- def __init__(self, port, protocol, backlog=None, interface=''):
- SocketListener.__init__(self, protocol, backlog=backlog)
+ def __init__(self, protocol_class, port, interface, hosts_allow):
self.port = port
self.interface = interface
-
+ self.hosts_allow = hosts_allow
+ connection.SocketListener.__init__(self, protocol_class)
+
+
def createSocket(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -49,11 +54,23 @@
else:
raise
- def acceptConnection(self, sock, protocol, addr):
- return SocketServerConnection(sock, protocol, addr, self)
+ def acceptConnection(self, sock, addrport):
+ addr = addrport[0]
+ if self.hosts_allow is None:
+ 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
-def listenTCP(port, protocol, interface='', backlog=None):
- l = TCPListener(port, protocol, interface=interface, backlog=backlog)
- l.listen()
- l.setCloExec()
+ try:
+ log.warn("Rejected connection from %s:%d (%s) for port %d.",
+ addr, addrport[1], fqdn, self.port)
+ sock.close()
+ except:
+ pass
diff -r 566395e5a14f -r 58397be18c52 tools/python/xen/web/unix.py
--- a/tools/python/xen/web/unix.py Mon Dec 12 16:32:50 2005
+++ b/tools/python/xen/web/unix.py Mon Dec 12 16:43:48 2005
@@ -21,15 +21,15 @@
import os
import os.path
-from connection import *
+import connection
-class UnixListener(SocketListener):
+class UnixListener(connection.SocketListener):
+ def __init__(self, path, protocol_class):
+ self.path = path
+ connection.SocketListener.__init__(self, protocol_class)
- def __init__(self, path, protocol, backlog=None):
- SocketListener.__init__(self, protocol, backlog=backlog)
- self.path = path
-
+
def createSocket(self):
pathdir = os.path.dirname(self.path)
if not os.path.exists(pathdir):
@@ -45,9 +45,6 @@
sock.bind(self.path)
return sock
- def acceptConnection(self, sock, protocol, addr):
- return SocketServerConnection(sock, protocol, self.path, self)
-
-def listenUNIX(path, protocol, backlog=None):
- UnixListener(path, protocol, backlog=backlog).listen()
+ def acceptConnection(self, sock, _):
+ connection.SocketServerConnection(sock, self.protocol_class)
diff -r 566395e5a14f -r 58397be18c52 tools/python/xen/xend/XendRoot.py
--- a/tools/python/xen/xend/XendRoot.py Mon Dec 12 16:32:50 2005
+++ b/tools/python/xen/xend/XendRoot.py Mon Dec 12 16:43:48 2005
@@ -74,6 +74,8 @@
"""Default port xend serves relocation at. """
xend_relocation_port_default = '8002'
+
+ xend_relocation_hosts_allow_default = ''
"""Default for the flag indicating whether xend should run a unix-domain
server."""
xend_unix_server_default = 'yes'
@@ -194,6 +196,10 @@
"""
return self.get_config_int('xend-relocation-port',
self.xend_relocation_port_default)
+ def get_xend_relocation_hosts_allow(self):
+ return self.get_config_value("xend-relocation-hosts-allow",
+ self.xend_relocation_hosts_allow_default)
+
def get_xend_address(self):
"""Get the address xend listens at for its HTTP port.
This defaults to the empty string which allows all hosts to connect.
diff -r 566395e5a14f -r 58397be18c52 tools/python/xen/xend/server/relocate.py
--- a/tools/python/xen/xend/server/relocate.py Mon Dec 12 16:32:50 2005
+++ b/tools/python/xen/xend/server/relocate.py Mon Dec 12 16:43:48 2005
@@ -16,6 +16,7 @@
# Copyright (C) 2005 XenSource Ltd
#============================================================================
+import re
import sys
import StringIO
@@ -116,8 +117,16 @@
xroot = XendRoot.instance()
if xroot.get_xend_unix_server():
path = '/var/lib/xend/relocation-socket'
- unix.listenUNIX(path, RelocationProtocol)
+ unix.UnixListener(path, RelocationProtocol)
if xroot.get_xend_relocation_server():
port = xroot.get_xend_relocation_port()
interface = xroot.get_xend_relocation_address()
- tcp.listenTCP(port, RelocationProtocol, interface=interface)
+
+ hosts_allow = xroot.get_xend_relocation_hosts_allow()
+ if hosts_allow == '':
+ hosts_allow = None
+ else:
+ hosts_allow = map(re.compile, hosts_allow.split(" "))
+
+ tcp.TCPListener(RelocationProtocol, port, interface = interface,
+ hosts_allow = hosts_allow)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|