33import io .sentrius .sso .automation .auditing .Trigger ;
44import io .sentrius .sso .automation .auditing .TriggerAction ;
55import io .sentrius .sso .core .model .ConnectedSystem ;
6+ import io .sentrius .sso .core .model .HostSystem ;
67import io .sentrius .sso .core .services .terminal .SessionTrackingService ;
78import io .sentrius .sso .sshproxy .config .SshProxyConfig ;
9+ import io .sentrius .sso .sshproxy .service .HostSystemSelectionService ;
810import io .sentrius .sso .sshproxy .service .InlineTerminalResponseService ;
911import io .sentrius .sso .sshproxy .service .SshCommandProcessor ;
1012import lombok .RequiredArgsConstructor ;
@@ -36,6 +38,7 @@ public class SshProxyShellHandler implements Factory<Command> {
3638 private final SessionTrackingService sessionTrackingService ;
3739 private final SshCommandProcessor commandProcessor ;
3840 private final InlineTerminalResponseService terminalResponseService ;
41+ private final HostSystemSelectionService hostSystemSelectionService ;
3942 private final SshProxyConfig config ;
4043
4144 // Track active sessions
@@ -58,6 +61,7 @@ private class SshProxyShell implements Command {
5861 private Environment environment ;
5962 private ServerSession session ;
6063 private ConnectedSystem connectedSystem ;
64+ private HostSystem selectedHostSystem ;
6165 private Thread shellThread ;
6266 private volatile boolean running = false ;
6367
@@ -94,6 +98,7 @@ public void start(ChannelSession channel, Environment env) throws IOException {
9498 // Initialize Sentrius session tracking
9599 try {
96100 initializeSentriusSession (username , sessionId );
101+ initializeHostSystemSelection ();
97102 sendWelcomeMessage ();
98103 startShellLoop ();
99104 } catch (Exception e ) {
@@ -116,7 +121,26 @@ private void initializeSentriusSession(String username, String sessionId) {
116121 log .info ("Initialized Sentrius session for user: {}" , username );
117122 }
118123
124+ private void initializeHostSystemSelection () {
125+ // Try to get a default HostSystem from the database
126+ selectedHostSystem = hostSystemSelectionService .getDefaultHostSystem ().orElse (null );
127+
128+ if (selectedHostSystem == null || !hostSystemSelectionService .isHostSystemValid (selectedHostSystem )) {
129+ log .warn ("No valid HostSystem found for SSH proxy session" );
130+ } else {
131+ log .info ("Selected HostSystem: {} ({}:{})" ,
132+ selectedHostSystem .getDisplayName (),
133+ selectedHostSystem .getHost (),
134+ selectedHostSystem .getPort ());
135+ }
136+ }
137+
119138 private void sendWelcomeMessage () throws IOException {
139+ String hostInfo = selectedHostSystem != null
140+ ? String .format ("%s (%s:%d)" , selectedHostSystem .getDisplayName (),
141+ selectedHostSystem .getHost (), selectedHostSystem .getPort ())
142+ : "No target host configured" ;
143+
120144 String welcome = "\r \n " +
121145 "╔══════════════════════════════════════════════════════════════╗\r \n " +
122146 "║ SENTRIUS SSH PROXY ║\r \n " +
@@ -125,14 +149,17 @@ private void sendWelcomeMessage() throws IOException {
125149 "\r \n " +
126150 "Welcome! This SSH session is protected by Sentrius safeguards.\r \n " +
127151 "All commands are monitored and may be blocked based on security policies.\r \n " +
152+ "\r \n " +
153+ "Target Host: " + hostInfo + "\r \n " +
128154 "\r \n " ;
129155
130156 terminalResponseService .sendMessage (welcome , out );
131157 sendPrompt ();
132158 }
133159
134160 private void sendPrompt () throws IOException {
135- String prompt = String .format ("[sentrius@%s]$ " , config .getTargetSsh ().getDefaultHost ());
161+ String hostname = selectedHostSystem != null ? selectedHostSystem .getHost () : "unknown" ;
162+ String prompt = String .format ("[sentrius@%s]$ " , hostname );
136163 terminalResponseService .sendMessage (prompt , out );
137164 }
138165
@@ -214,6 +241,7 @@ private void processCommand(String command) throws IOException {
214241
215242 private boolean handleBuiltinCommand (String command ) throws IOException {
216243 String cmd = command .toLowerCase ().trim ();
244+ String [] parts = command .trim ().split ("\\ s+" );
217245
218246 switch (cmd ) {
219247 case "exit" :
@@ -231,17 +259,27 @@ private boolean handleBuiltinCommand(String command) throws IOException {
231259 showStatus ();
232260 return true ;
233261
262+ case "hosts" :
263+ showAvailableHosts ();
264+ return true ;
265+
234266 default :
267+ if (parts .length >= 2 && "connect" .equals (parts [0 ].toLowerCase ())) {
268+ return handleConnectCommand (parts );
269+ }
235270 return false ;
236271 }
237272 }
238273
239274 private void showHelp () throws IOException {
240275 String help = "\r \n " +
241276 "Sentrius SSH Proxy - Built-in Commands:\r \n " +
242- " help - Show this help message\r \n " +
243- " status - Show session status\r \n " +
244- " exit - Close SSH session\r \n " +
277+ " help - Show this help message\r \n " +
278+ " status - Show session status\r \n " +
279+ " hosts - List available target hosts\r \n " +
280+ " connect <id> - Connect to HostSystem by ID\r \n " +
281+ " connect <name> - Connect to HostSystem by display name\r \n " +
282+ " exit - Close SSH session\r \n " +
245283 "\r \n " +
246284 "All other commands are forwarded to the target SSH server\r \n " +
247285 "and subject to Sentrius security policies.\r \n \r \n " ;
@@ -250,21 +288,99 @@ private void showHelp() throws IOException {
250288 }
251289
252290 private void showStatus () throws IOException {
291+ String hostInfo = selectedHostSystem != null
292+ ? String .format ("%s (%s:%d)" , selectedHostSystem .getDisplayName (),
293+ selectedHostSystem .getHost (), selectedHostSystem .getPort ())
294+ : "No target host configured" ;
295+
253296 String status = String .format ("\r \n " +
254297 "Sentrius SSH Proxy Status:\r \n " +
255298 " User: %s\r \n " +
256- " Target Host: %s:%d \r \n " +
299+ " Target Host: %s\r \n " +
257300 " Session Active: %s\r \n " +
258301 " Safeguards: ENABLED\r \n \r \n " ,
259302 session .getUsername (),
260- config .getTargetSsh ().getDefaultHost (),
261- config .getTargetSsh ().getDefaultPort (),
303+ hostInfo ,
262304 running ? "YES" : "NO"
263305 );
264306
265307 terminalResponseService .sendMessage (status , out );
266308 }
267309
310+ private void showAvailableHosts () throws IOException {
311+ var hostSystems = hostSystemSelectionService .getAllHostSystems ();
312+
313+ StringBuilder hostList = new StringBuilder ("\r \n Available HostSystems:\r \n " );
314+ hostList .append ("ID\t Name\t \t \t Host:Port\t \t Status\r \n " );
315+ hostList .append ("────────────────────────────────────────────────────────────\r \n " );
316+
317+ if (hostSystems .isEmpty ()) {
318+ hostList .append ("No HostSystems configured in database.\r \n " );
319+ } else {
320+ for (HostSystem hs : hostSystems ) {
321+ String name = hs .getDisplayName () != null ? hs .getDisplayName () : "N/A" ;
322+ String hostPort = String .format ("%s:%d" , hs .getHost (), hs .getPort ());
323+ String status = hostSystemSelectionService .isHostSystemValid (hs ) ? "Valid" : "Invalid" ;
324+ String current = (selectedHostSystem != null && selectedHostSystem .getId ().equals (hs .getId ())) ? " *" : "" ;
325+
326+ hostList .append (String .format ("%d\t %-15s\t %-15s\t %s%s\r \n " ,
327+ hs .getId (), name , hostPort , status , current ));
328+ }
329+ hostList .append ("\r \n * = Current selection\r \n " );
330+ }
331+ hostList .append ("\r \n " );
332+
333+ terminalResponseService .sendMessage (hostList .toString (), out );
334+ }
335+
336+ private boolean handleConnectCommand (String [] parts ) throws IOException {
337+ if (parts .length < 2 ) {
338+ terminalResponseService .sendMessage ("Usage: connect <id|name>\r \n " , out );
339+ return true ;
340+ }
341+
342+ String target = parts [1 ];
343+ HostSystem targetHost = null ;
344+
345+ // Try to parse as ID first
346+ try {
347+ Long id = Long .parseLong (target );
348+ targetHost = hostSystemSelectionService .getHostSystemById (id ).orElse (null );
349+ } catch (NumberFormatException e ) {
350+ // Not a number, try by display name
351+ var hostsByName = hostSystemSelectionService .getHostSystemsByDisplayName (target );
352+ if (!hostsByName .isEmpty ()) {
353+ targetHost = hostsByName .get (0 );
354+ if (hostsByName .size () > 1 ) {
355+ terminalResponseService .sendMessage (
356+ String .format ("Warning: Multiple hosts found with name '%s', using first one.\r \n " , target ), out );
357+ }
358+ }
359+ }
360+
361+ if (targetHost == null ) {
362+ terminalResponseService .sendMessage (
363+ String .format ("Error: HostSystem '%s' not found.\r \n " , target ), out );
364+ return true ;
365+ }
366+
367+ if (!hostSystemSelectionService .isHostSystemValid (targetHost )) {
368+ terminalResponseService .sendMessage (
369+ String .format ("Error: HostSystem '%s' is not properly configured.\r \n " , target ), out );
370+ return true ;
371+ }
372+
373+ selectedHostSystem = targetHost ;
374+ terminalResponseService .sendMessage (
375+ String .format ("Connected to HostSystem: %s (%s:%d)\r \n " ,
376+ targetHost .getDisplayName (), targetHost .getHost (), targetHost .getPort ()), out );
377+
378+ log .info ("SSH proxy session switched to HostSystem: {} ({}:{})" ,
379+ targetHost .getDisplayName (), targetHost .getHost (), targetHost .getPort ());
380+
381+ return true ;
382+ }
383+
268384 private void executeCommand (String command ) throws IOException {
269385 // TODO: Implement actual command forwarding to target SSH server
270386 // For now, simulate command execution
0 commit comments