By Admin on Friday, 27 March 2026
Category: All

SSH Client sgcIndy Delphi Component

Remote server administration, automated deployments, configuration management, and infrastructure monitoring — all of these rely on secure shell access. Whether you need to execute a single command on a remote host, open an interactive terminal session, or set up a port-forwarding tunnel, SSH is the protocol that makes it possible.

The sgcIndy package includes TIdSSHClient — a native Delphi SSH client component that implements the SSH-2 protocol with full support for command execution, interactive shells, pseudo-terminal allocation, port forwarding, keep-alive, and modern cryptographic algorithms. No external SSH executables, no DLL wrappers — pure Delphi component architecture with an event-driven API.

This article walks through the key features and provides Delphi code examples for the most common SSH use cases.

Key Features

Command Execution
Execute remote commands and capture stdout, stderr, and exit codes. One-line convenience method or full channel-based control.
Interactive Shell
Open interactive shell sessions with pseudo-terminal support. Send commands, receive output asynchronously, and handle terminal resize.
Port Forwarding
Set up direct TCP/IP tunnels and reverse forwarding. Access remote services through encrypted SSH tunnels.
Modern Cryptography
Curve25519, ECDH, AES-GCM, Ed25519 keys. Configurable algorithm negotiation with secure defaults out of the box.
Multiple Auth Methods
Password, public key (RSA, ECDSA, Ed25519), and keyboard-interactive authentication. Host key verification via event callback.
Multi-Channel
Up to 10 concurrent channels per connection. Run multiple commands, shells, or tunnels simultaneously over a single SSH session.

Quick Start — Execute a Remote Command

The simplest use case: connect, run a command, get the output, and disconnect — all in a few lines.

var
  oSSH: TIdSSHClient;
  vOutput: string;
begin
  oSSH := TIdSSHClient.Create(nil);
  Try
    oSSH.Host := 'server.example.com';
    oSSH.Port := 22;
    oSSH.Authentication.Username := 'admin';
    oSSH.Authentication.Password := 'secret';
    oSSH.Connect;

    // Execute a command and capture the output
    vOutput := oSSH.Execute('df -h');
    WriteLn(vOutput);

    oSSH.Disconnect;
  Finally
    oSSH.Free;
  End;
end;

One-liner. The Execute method opens a channel, runs the command, waits for the result, and returns the output as a string — perfect for scripted automation.

Authentication

Three authentication methods are supported. All three are enabled by default and the client negotiates automatically with the server.

Password

oSSH.Authentication.Username := 'admin';
oSSH.Authentication.Password := 'secret';

Public Key

oSSH.Authentication.Username := 'deploy';
oSSH.Authentication.PrivateKeyFile := 'C:\keys\id_ed25519';
oSSH.Authentication.PublicKeyFile := 'C:\keys\id_ed25519.pub';
oSSH.Authentication.Passphrase := 'keypassphrase';

Keyboard-Interactive

Handle multi-step authentication prompts (MFA, OTP, security questions) through the OnSSHKeyboardInteractive event.

oSSH.OnSSHKeyboardInteractive := OnKeyboardInteractive;

procedure TForm1.OnKeyboardInteractive(Sender: TObject;
  const aName, aInstruction: string;
  aPrompts: TStrings; aEchos: TList; aResponses: TStrings);
begin
  // Respond to each prompt (e.g., "Password:", "OTP:")
  if aPrompts.Count > 0 then
    aResponses.Add('mypassword');
end;

Host Key Verification

oSSH.OnSSHHostKey := OnHostKey;

procedure TForm1.OnHostKey(Sender: TObject;
  const aHostKeyType, aFingerprint: string;
  var aAction: TIdSSHHostKeyVerification);
begin
  // Accept or reject based on known fingerprint
  aAction := sshHostKeyAccept;
end;

Command Execution

Two approaches for running remote commands: the convenience Execute method for simple cases, or the channel-based API for full control over input, output, and exit status.

Simple: Execute Method

// Execute and get output (30-second timeout by default)
vOutput := oSSH.Execute('ls -la /var/log');

// Custom timeout (10 seconds)
vOutput := oSSH.Execute('cat /etc/hostname', 10000);

Advanced: Channel-Based Execution

For asynchronous execution with separate stdout/stderr handling and exit status tracking.

// Open a channel and execute a command
var
  vChannelId: Cardinal;
begin
  vChannelId := oSSH.OpenChannel;
  oSSH.RequestExec(vChannelId, 'tar czf /tmp/backup.tar.gz /data');
  // Output arrives via OnSSHChannelData event
  // Exit status arrives via OnSSHChannelExitStatus event
end;

// Handle stdout
procedure TForm1.OnChannelData(Sender: TObject;
  aChannelId: Cardinal; const aData: TIdBytes);
begin
  Memo1.Lines.Add(BytesToString(aData));
end;

// Handle stderr
procedure TForm1.OnChannelExtendedData(Sender: TObject;
  aChannelId: Cardinal; aDataType: Cardinal; const aData: TIdBytes);
begin
  MemoErrors.Lines.Add(BytesToString(aData));
end;

// Handle exit status
procedure TForm1.OnExitStatus(Sender: TObject;
  aChannelId: Cardinal; aExitStatus: Integer);
begin
  WriteLn('Command exited with code: ' + IntToStr(aExitStatus));
end;

Interactive Shell Sessions

Open a pseudo-terminal and interact with a remote shell — ideal for building SSH terminal emulators or automating interactive CLI workflows.

// Open channel, request PTY, then request shell
var
  vChannelId: Cardinal;
begin
  vChannelId := oSSH.OpenChannel;

  // Request a pseudo-terminal (xterm, 80x24)
  oSSH.RequestPTY(vChannelId, 'xterm', 80, 24);

  // Start the shell
  oSSH.RequestShell(vChannelId);

  // Send commands to the shell
  oSSH.SendChannelData(vChannelId, 'cd /var/log' + #13#10);
  oSSH.SendChannelData(vChannelId, 'tail -f syslog' + #13#10);
end;

Terminal Resize & Signals

// Notify the server of terminal resize
oSSH.SendWindowChange(vChannelId, 120, 40, 0, 0);

// Send Ctrl+C (interrupt signal)
oSSH.SendSignal(vChannelId, 'INT');

// Set an environment variable before running commands
oSSH.SetEnvironmentVariable(vChannelId, 'LANG', 'en_US.UTF-8');

// Signal end of input
oSSH.SendEOF(vChannelId);

Port Forwarding (SSH Tunnels)

Create encrypted tunnels to access remote services as if they were local. Useful for securely accessing databases, admin panels, or internal APIs behind firewalls.

Direct TCP/IP Tunneling (Local Forward)

// Tunnel to a remote database through SSH
var
  vTunnelId: Cardinal;
begin
  vTunnelId := oSSH.OpenDirectTCPIP(
    'db-internal.example.com',  // Remote host
    5432,                        // Remote port (PostgreSQL)
    '127.0.0.1',                 // Originator IP
    0);                           // Originator port

  // Send/receive data through the tunnel
  oSSH.SendChannelData(vTunnelId, vDatabaseQuery);
end;

Reverse Forwarding (Remote Forward)

// Ask the server to forward a remote port to us
oSSH.RequestForwarding('0.0.0.0', 8080);

// Cancel the forwarding
oSSH.CancelForwarding('0.0.0.0', 8080);

Keep-Alive & Connection Options

Prevent idle connections from being dropped by firewalls or load balancers with the built-in keep-alive mechanism.

// Send keep-alive every 30 seconds, disconnect after 3 failures
oSSH.KeepAlive.Enabled := True;
oSSH.KeepAlive.Interval := 30;
oSSH.KeepAlive.MaxCount := 3;

// Connection options
oSSH.SSHOptions.ConnectTimeout := 10000;  // 10 seconds
oSSH.SSHOptions.ReadTimeout := 30000;     // 30 seconds
oSSH.SSHOptions.MaxChannels := 10;       // Concurrent channels

Cryptographic Algorithm Configuration

The defaults are secure and modern. Customize algorithm negotiation when compliance policies or legacy server compatibility demand it.

Category Supported Algorithms
Key Exchange Curve25519, ECDH (P-256, P-384, P-521), DH Group14/16
Host Keys Ed25519, ECDSA (P-256, P-384, P-521), RSA (SHA2-256, SHA2-512)
Ciphers AES-256/192/128-CTR, AES-256/128-GCM
MACs HMAC-SHA2-256, HMAC-SHA2-512, HMAC-SHA1
// Customize algorithm preferences
oSSH.Algorithms.KexAlgorithms := 'curve25519-sha256';
oSSH.Algorithms.Ciphers := This email address is being protected from spambots. You need JavaScript enabled to view it.,aes256-ctr';
oSSH.Algorithms.HostKeyAlgorithms := 'ssh-ed25519,rsa-sha2-256';
oSSH.Algorithms.MACs := 'hmac-sha2-256';

// Force re-keying to refresh encryption
oSSH.Rekey;

Events Reference

The component provides granular event callbacks for every stage of the SSH lifecycle.

Event Fired When
OnSSHConnectSSH connection established
OnSSHDisconnectSSH connection closes (with reason and code)
OnSSHErrorSSH error occurs
OnSSHAuthSuccess / OnSSHAuthFailureAuthentication succeeds or fails
OnSSHHostKeyHost key needs verification (accept/reject)
OnSSHChannelDataData (stdout) received on a channel
OnSSHChannelExtendedDataExtended data (stderr) received on a channel
OnSSHChannelExitStatusRemote command exit code received
OnSSHChannelExitSignalRemote process terminated by signal (with signal name)
OnSSHKeyboardInteractiveServer requests keyboard-interactive responses
OnSSHAuthBannerServer sends an authentication banner message

Complete Example: Automated Deployment Script

A fully configured SSH client that connects with key authentication, runs deployment commands, and captures exit status.

uses
  IdSSHClient, IdSSHClasses;

var
  oSSH: TIdSSHClient;
  vOutput: string;
begin
  oSSH := TIdSSHClient.Create(nil);
  Try
    // Connection
    oSSH.Host := 'production.example.com';
    oSSH.Port := 22;

    // Key-based authentication
    oSSH.Authentication.Username := 'deploy';
    oSSH.Authentication.PrivateKeyFile := 'C:\keys\deploy_ed25519';

    // Keep connection alive through firewalls
    oSSH.KeepAlive.Enabled := True;
    oSSH.KeepAlive.Interval := 30;

    // Events
    oSSH.OnSSHHostKey := OnHostKey;
    oSSH.OnSSHError := OnError;

    // Connect
    oSSH.Connect;

    // Run deployment commands
    vOutput := oSSH.Execute('cd /opt/app && git pull origin main');
    WriteLn(vOutput);

    vOutput := oSSH.Execute('systemctl restart myapp');
    WriteLn(vOutput);

    vOutput := oSSH.Execute('systemctl status myapp');
    WriteLn(vOutput);

    // Disconnect
    oSSH.Disconnect;
  Finally
    oSSH.Free;
  End;
end;

Related Posts