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@xensource.com>
This commit is contained in:
emellor@leeni.uk.xensource.com committed 2005-12-12 16:43:48 +00:00
1 parent 91da6b2f1c
commit 03bbc8cec6
5 files changed
+77 -63

No files matched your search

+23 -38
View File
@@ -19,7 +19,6 @@
import sys
import threading
import select
import socket
import fcntl
@@ -31,21 +30,17 @@ for TCP and unix-domain sockets (see tcp.py and unix.py).
"""
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 @@ class SocketServerConnection:
pass
def close(self):
self.sock.close()
def write(self, data):
self.sock.send(data)
@@ -77,52 +76,38 @@ class SocketListener:
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()
+29 -12
View File
@@ -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 @@ class TCPListener(SocketListener):
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
+8 -11
View File
@@ -21,15 +21,15 @@ import socket
import os
import os.path
from connection import *
import connection
class UnixListener(SocketListener):
def __init__(self, path, protocol, backlog=None):
SocketListener.__init__(self, protocol, backlog=backlog)
class UnixListener(connection.SocketListener):
def __init__(self, path, protocol_class):
self.path = path
connection.SocketListener.__init__(self, protocol_class)
def createSocket(self):
pathdir = os.path.dirname(self.path)
if not os.path.exists(pathdir):
@@ -45,9 +45,6 @@ class UnixListener(SocketListener):
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)
+6
View File
@@ -75,6 +75,8 @@ class XendRoot:
"""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 @@ class XendRoot:
"""
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.
+11 -2
View File
@@ -16,6 +16,7 @@
# Copyright (C) 2005 XenSource Ltd
#============================================================================
import re
import sys
import StringIO
@@ -116,8 +117,16 @@ def listenRelocation():
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)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.