From: Ondrej Lichtner <olichtne(a)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(a)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(a)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())
--
2.7.2