From: Ondrej Lichtner olichtne@redhat.com
This patch replaces the sockets used for the Controller<->Slave communication with CtlSecSocket and SlaveSecSocket. This includes some changes to the ConnectionHandler by adding SecureSocket support and removing the socket support since it's not needed anymore (at least for now).
Caution: Right now this breaks the functionality of the lnst-ctl deconfigure command and the lnst-pool-wizard, which are at the moment not able to use the secured sockets.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com --- lnst/Common/ConnectionHandler.py | 39 ++++++++++----------------------------- lnst/Controller/Machine.py | 5 ++++- lnst/Slave/NetTestSlave.py | 13 +++++++++++-- 3 files changed, 25 insertions(+), 32 deletions(-)
diff --git a/lnst/Common/ConnectionHandler.py b/lnst/Common/ConnectionHandler.py index 36349dc..5d3170a 100644 --- a/lnst/Common/ConnectionHandler.py +++ b/lnst/Common/ConnectionHandler.py @@ -12,19 +12,15 @@ olichtne@redhat.com (Ondrej Lichtner) """
import select -import cPickle import socket from _multiprocessing import Connection from pyroute2 import IPRSocket +from lnst.Common.SecureSocket import SecureSocket, SecSocketException
def send_data(s, data): try: - if isinstance(s, socket.SocketType): - pickled_data = cPickle.dumps(data) - length = len(pickled_data) - - data_to_send = str(length) + " " + pickled_data - s.sendall(data_to_send) + if isinstance(s, SecureSocket): + s.send_msg(data) elif isinstance(s, Connection): s.send(data) else: @@ -37,27 +33,11 @@ def recv_data(s): if isinstance(s, IPRSocket): msg = s.get() data = {"type": "netlink", "data": msg} - elif isinstance(s, socket.SocketType): - length = "" - while True: - c = s.recv(1) - if c == ' ': - length = int(length) - break - elif c == "": - return "" - else: - length += c - data = "" - - while len(data)<length: - c = s.recv(length - len(data)) - if c == "": - return "" - else: - data += c - - data = cPickle.loads(data) + elif isinstance(s, SecureSocket): + try: + data = s.recv_msg() + except SecSocketException: + return "" elif isinstance(s, Connection): data = s.recv() else: @@ -95,10 +75,11 @@ class ConnectionHandler(object): f.close() self.remove_connection(f) f_ready = False - else: + elif data is not None: id = self.get_connection_id(f) requests.append((id, data))
+ if f_ready: #poll the file descriptor if there is another message rll, _, _ = select.select([f], [], [], 0) if rll == []: diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py index 62393b8..839ec16 100644 --- a/lnst/Controller/Machine.py +++ b/lnst/Controller/Machine.py @@ -23,6 +23,7 @@ from lnst.Common.NetUtils import normalize_hwaddr from lnst.Common.Utils import wait_for, create_tar_archive from lnst.Common.Utils import check_process_running from lnst.Common.NetTestCommand import DEFAULT_TIMEOUT +from lnst.Controller.CtlSecSocket import CtlSecSocket
# conditional support for libvirt if check_process_running("libvirtd"): @@ -215,7 +216,9 @@ class Machine(object): m_id = self._id
logging.info("Connecting to RPC on machine %s (%s)", m_id, hostname) - connection = socket.create_connection((hostname, port)) + connection = CtlSecSocket(socket.create_connection((hostname, port))) + connection.handshake(self._security) + self._msg_dispatcher.add_slave(self, connection)
hello, slave_desc = self._rpc_call("hello", recipe_name) diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py index 1428497..3b8bf79 100644 --- a/lnst/Slave/NetTestSlave.py +++ b/lnst/Slave/NetTestSlave.py @@ -37,6 +37,7 @@ from lnst.Common.Config import lnst_config from lnst.Common.Config import DefaultRPCPort from lnst.Slave.InterfaceManager import InterfaceManager from lnst.Slave.BridgeTool import BridgeTool +from lnst.Slave.SlaveSecSocket import SlaveSecSocket, SecSocketException
class SlaveMethods: ''' @@ -837,11 +838,19 @@ class ServerHandler(ConnectionHandler): self._netns = None self._c_socket = None
+ self._security = lnst_config.get_section_values("security") + def accept_connection(self): self._c_socket, addr = self._s_socket.accept() - self._c_socket = (self._c_socket, addr[0]) + self._c_socket = (SlaveSecSocket(self._c_socket), addr[0]) logging.info("Recieved connection from %s" % self._c_socket[1])
+ try: + self._c_socket[0].handshake(self._security) + except: + self.close_c_sock() + raise + self.add_connection(self._c_socket[1], self._c_socket[0]) return self._c_socket
@@ -974,7 +983,7 @@ class NetTestSlave: try: logging.info("Waiting for connection.") self._server_handler.accept_connection() - except socket.error: + except (socket.error, SecSocketException): continue self._log_ctl.set_connection( self._server_handler.get_ctl_sock())