#2781 - user_session_manager._timeout_session() now sends a user_timeout command when closing remote sessions. Corrected source_ip in Terminal.receive()
This commit is contained in:
@@ -80,14 +80,14 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Login to the remote (node_b) from local (node_a)\n",
|
"# Login to the remote (node_b) from local (node_a)\n",
|
||||||
"term_a_term_b_remote_connection: RemoteTerminalConnection = terminal_a.login(username=\"admin\", password=\"Admin123!\", ip_address=\"192.168.0.11\")"
|
"term_a_term_b_remote_connection: RemoteTerminalConnection = terminal_a.login(username=\"admin\", password=\"admin\", ip_address=\"192.168.0.11\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"You can view all active connections to a terminal through use of the `show()` method"
|
"You can view all active connections to a terminal through use of the `show()` method, "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,11 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"terminal_b.show()"
|
"terminal_b.show()\n",
|
||||||
|
"print(term_a_term_b_remote_connection.ssh_session_id)\n",
|
||||||
|
"computer_b.user_session_manager.show(include_session_id=True)\n",
|
||||||
|
"computer_b.user_session_manager.show()\n",
|
||||||
|
"\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -183,6 +187,22 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"terminal_b.show()"
|
"terminal_b.show()"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Disconnected Terminal sessions will no longer show in the node's `user_session_manager` as active, but will be under the historic sessions"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"computer_b.user_session_manager.show(include_historic=True, include_session_id=True)"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
@@ -1294,6 +1294,13 @@ class UserSessionManager(Service):
|
|||||||
self.remote_sessions.pop(session.uuid)
|
self.remote_sessions.pop(session.uuid)
|
||||||
session_type = "Remote"
|
session_type = "Remote"
|
||||||
session_identity = f"{session_identity} {session.remote_ip_address}"
|
session_identity = f"{session_identity} {session.remote_ip_address}"
|
||||||
|
self.parent.terminal._connections.pop(session.uuid)
|
||||||
|
software_manager: SoftwareManager = self.software_manager
|
||||||
|
software_manager.send_payload_to_session_manager(
|
||||||
|
payload={"type": "user_timeout", "connection_id": session.uuid},
|
||||||
|
dest_port=Port.SSH,
|
||||||
|
dest_ip_address=session.remote_ip_address,
|
||||||
|
)
|
||||||
|
|
||||||
self.sys_log.info(f"{self.name}: {session_type} {session_identity} session timeout due to inactivity")
|
self.sys_log.info(f"{self.name}: {session_type} {session_identity} session timeout due to inactivity")
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ class TerminalClientConnection(BaseModel):
|
|||||||
parent_terminal: Terminal
|
parent_terminal: Terminal
|
||||||
"""The parent Node that this connection was created on."""
|
"""The parent Node that this connection was created on."""
|
||||||
|
|
||||||
session_id: str = None
|
ssh_session_id: str = None
|
||||||
"""Session ID that connection is linked to"""
|
"""Session ID that connection is linked to, used for sending commands via session manager."""
|
||||||
|
|
||||||
connection_uuid: str = None
|
connection_uuid: str = None
|
||||||
"""Connection UUID"""
|
"""Connection UUID"""
|
||||||
@@ -52,7 +52,9 @@ class TerminalClientConnection(BaseModel):
|
|||||||
"""Flag to state whether the connection is active or not"""
|
"""Flag to state whether the connection is active or not"""
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"{self.__class__.__name__}(connection_id='{self.connection_uuid}')"
|
return (
|
||||||
|
f"{self.__class__.__name__}(connection_id: '{self.connection_uuid}, ssh_session_id: {self.ssh_session_id}')"
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
@@ -124,13 +126,14 @@ class RemoteTerminalConnection(TerminalClientConnection):
|
|||||||
ssh_command=command,
|
ssh_command=command,
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.parent_terminal.send(payload=payload, session_id=self.session_id)
|
return self.parent_terminal.send(payload=payload, session_id=self.ssh_session_id)
|
||||||
|
|
||||||
|
|
||||||
class Terminal(Service):
|
class Terminal(Service):
|
||||||
"""Class used to simulate a generic terminal service. Can be interacted with by other terminals via SSH."""
|
"""Class used to simulate a generic terminal service. Can be interacted with by other terminals via SSH."""
|
||||||
|
|
||||||
_client_connection_requests: Dict[str, Optional[Union[str, TerminalClientConnection]]] = {}
|
_client_connection_requests: Dict[str, Optional[Union[str, TerminalClientConnection]]] = {}
|
||||||
|
"""Dictionary of connect requests made to remote nodes."""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
kwargs["name"] = "Terminal"
|
kwargs["name"] = "Terminal"
|
||||||
@@ -169,7 +172,14 @@ class Terminal(Service):
|
|||||||
def _login(request: RequestFormat, context: Dict) -> RequestResponse:
|
def _login(request: RequestFormat, context: Dict) -> RequestResponse:
|
||||||
login = self._process_local_login(username=request[0], password=request[1])
|
login = self._process_local_login(username=request[0], password=request[1])
|
||||||
if login:
|
if login:
|
||||||
return RequestResponse(status="success", data={})
|
return RequestResponse(
|
||||||
|
status="success",
|
||||||
|
data={
|
||||||
|
"connection ID": login.connection_uuid,
|
||||||
|
"ssh_session_id": login.ssh_session_id,
|
||||||
|
"ip_address": login.ip_address,
|
||||||
|
},
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return RequestResponse(status="failure", data={})
|
return RequestResponse(status="failure", data={})
|
||||||
|
|
||||||
@@ -184,16 +194,13 @@ class Terminal(Service):
|
|||||||
"""Execute an instruction."""
|
"""Execute an instruction."""
|
||||||
command: str = request[0]
|
command: str = request[0]
|
||||||
connection_id: str = request[1]
|
connection_id: str = request[1]
|
||||||
self.execute(command, connection_id=connection_id)
|
return self.execute(command, connection_id=connection_id)
|
||||||
return RequestResponse(status="success", data={})
|
|
||||||
|
|
||||||
def _logoff(request: RequestFormat, context: Dict) -> RequestResponse:
|
def _logoff(request: RequestFormat, context: Dict) -> RequestResponse:
|
||||||
"""Logoff from connection."""
|
"""Logoff from connection."""
|
||||||
connection_uuid = request[0]
|
connection_uuid = request[0]
|
||||||
# TODO: Uncomment this when UserSessionManager merged.
|
self.parent.user_session_manager.local_logout(connection_uuid)
|
||||||
# self.parent.UserSessionManager.logoff(connection_uuid)
|
|
||||||
self._disconnect(connection_uuid)
|
self._disconnect(connection_uuid)
|
||||||
|
|
||||||
return RequestResponse(status="success", data={})
|
return RequestResponse(status="success", data={})
|
||||||
|
|
||||||
rm.add_request(
|
rm.add_request(
|
||||||
@@ -234,7 +241,7 @@ class Terminal(Service):
|
|||||||
new_connection = LocalTerminalConnection(
|
new_connection = LocalTerminalConnection(
|
||||||
parent_terminal=self,
|
parent_terminal=self,
|
||||||
connection_uuid=connection_uuid,
|
connection_uuid=connection_uuid,
|
||||||
session_id=session_id,
|
ssh_session_id=session_id,
|
||||||
time=datetime.now(),
|
time=datetime.now(),
|
||||||
)
|
)
|
||||||
self._connections[connection_uuid] = new_connection
|
self._connections[connection_uuid] = new_connection
|
||||||
@@ -288,11 +295,11 @@ class Terminal(Service):
|
|||||||
|
|
||||||
def _validate_client_connection_request(self, connection_id: str) -> bool:
|
def _validate_client_connection_request(self, connection_id: str) -> bool:
|
||||||
"""Check that client_connection_id is valid."""
|
"""Check that client_connection_id is valid."""
|
||||||
return True if connection_id in self._client_connection_requests else False
|
return connection_id in self._client_connection_requests
|
||||||
|
|
||||||
def _check_client_connection(self, connection_id: str) -> bool:
|
def _check_client_connection(self, connection_id: str) -> bool:
|
||||||
"""Check that client_connection_id is valid."""
|
"""Check that client_connection_id is valid."""
|
||||||
return True if connection_id in self._connections else False
|
return connection_id in self._connections
|
||||||
|
|
||||||
def _send_remote_login(
|
def _send_remote_login(
|
||||||
self,
|
self,
|
||||||
@@ -381,7 +388,7 @@ class Terminal(Service):
|
|||||||
"""
|
"""
|
||||||
client_connection = RemoteTerminalConnection(
|
client_connection = RemoteTerminalConnection(
|
||||||
parent_terminal=self,
|
parent_terminal=self,
|
||||||
session_id=session_id,
|
ssh_session_id=session_id,
|
||||||
connection_uuid=connection_id,
|
connection_uuid=connection_id,
|
||||||
ip_address=source_ip,
|
ip_address=source_ip,
|
||||||
connection_request_id=connection_request_id,
|
connection_request_id=connection_request_id,
|
||||||
@@ -398,7 +405,7 @@ class Terminal(Service):
|
|||||||
:param session_id: The session id the payload relates to.
|
:param session_id: The session id the payload relates to.
|
||||||
:return: True.
|
:return: True.
|
||||||
"""
|
"""
|
||||||
source_ip = kwargs["from_network_interface"].ip_address
|
source_ip = [kwargs["frame"].ip.src_ip_address][0]
|
||||||
self.sys_log.info(f"Received payload: {payload}. Source: {source_ip}")
|
self.sys_log.info(f"Received payload: {payload}. Source: {source_ip}")
|
||||||
if isinstance(payload, SSHPacket):
|
if isinstance(payload, SSHPacket):
|
||||||
if payload.transport_message == SSHTransportMessage.SSH_MSG_USERAUTH_REQUEST:
|
if payload.transport_message == SSHTransportMessage.SSH_MSG_USERAUTH_REQUEST:
|
||||||
@@ -470,12 +477,21 @@ class Terminal(Service):
|
|||||||
self._disconnect(payload["connection_id"])
|
self._disconnect(payload["connection_id"])
|
||||||
self.parent.user_session_manager.remote_logout(remote_session_id=connection_id)
|
self.parent.user_session_manager.remote_logout(remote_session_id=connection_id)
|
||||||
else:
|
else:
|
||||||
self.sys_log.info("No Active connection held for received connection ID.")
|
self.sys_log.error("No Active connection held for received connection ID.")
|
||||||
|
|
||||||
|
if payload["type"] == "user_timeout":
|
||||||
|
connection_id = payload["connection_id"]
|
||||||
|
valid_id = self._check_client_connection(connection_id)
|
||||||
|
if valid_id:
|
||||||
|
self._connections.pop(connection_id)
|
||||||
|
self.sys_log.info(f"{self.name}: Connection {connection_id} disconnected due to inactivity.")
|
||||||
|
else:
|
||||||
|
self.sys_log.error(f"{self.name}: Connection {connection_id} is invalid.")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _disconnect(self, connection_uuid: str) -> bool:
|
def _disconnect(self, connection_uuid: str) -> bool:
|
||||||
"""Disconnect from the remote.
|
"""Disconnect connection.
|
||||||
|
|
||||||
:param connection_uuid: Connection ID that we want to disconnect.
|
:param connection_uuid: Connection ID that we want to disconnect.
|
||||||
:return True if successful, False otherwise.
|
:return True if successful, False otherwise.
|
||||||
@@ -489,7 +505,7 @@ class Terminal(Service):
|
|||||||
|
|
||||||
if isinstance(connection, RemoteTerminalConnection):
|
if isinstance(connection, RemoteTerminalConnection):
|
||||||
# Send disconnect command via software manager
|
# Send disconnect command via software manager
|
||||||
session_id = connection.session_id
|
session_id = connection.ssh_session_id
|
||||||
|
|
||||||
software_manager: SoftwareManager = self.software_manager
|
software_manager: SoftwareManager = self.software_manager
|
||||||
software_manager.send_payload_to_session_manager(
|
software_manager.send_payload_to_session_manager(
|
||||||
|
|||||||
Reference in New Issue
Block a user