[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Added a hosts-allow facility to TCP connections, which allows us to restrict
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |