Komponent klienta SFTP sgcIndy dla Delphi

· Komponenty

Bezpieczny transfer plików pozostaje podstawą integracji korporacyjnej. Niezależnie od tego, czy wymieniasz dane z partnerami bankowymi, synchronizujesz pliki ze zdalnymi serwerami, czy automatyzujesz potoki wdrożeniowe, SFTP (SSH File Transfer Protocol) jest branżowym standardem bezpiecznego przesyłania plików przez niezaufane sieci.

Pakiet sgcIndy zawiera TIdSFTPClient — natywny komponent klienta SFTP dla Delphi działający przez SSH bez potrzeby zewnętrznych narzędzi wiersza poleceń lub plików wykonywalnych firm trzecich. Obsługuje przesyłanie i pobieranie plików, zarządzanie katalogami, dowiązania symboliczne, atrybuty plików, śledzenie postępu i nowoczesne algorytmy kryptograficzne — wszystko przez przejrzyste, zdarzeniowe API.

Ten artykuł omawia pełny zestaw funkcji i dostarcza gotowy kod Delphi dla najczęstszych operacji SFTP.

Kluczowe funkcje

Transfer plików
Przesyłaj i pobieraj pliki z konfigurowalnymi rozmiarami buforów i zdarzeniami postępu w czasie rzeczywistym. Transferuj z ścieżek plików lub bezpośrednio z obiektów TStream.
Operacje na katalogach
Wylistuj katalogi z pełnymi metadanymi, twórz i usuwaj katalogi oraz rozwiązuj ścieżki łącznie z dowiązaniami symbolicznymi.
Nowoczesna kryptografia
Curve25519, ECDH, AES-GCM, klucze Ed25519 i HMAC-SHA2. Konfigurowalna negocjacja algorytmów dla wymogów zgodności.
Wiele metod uwierzytelniania
Hasło, klucz publiczny (RSA, ECDSA, Ed25519) i uwierzytelnianie interaktywne z klawiatury. Weryfikacja klucza hosta z wywołaniami zwrotnymi odcisku palca.
Atrybuty i uprawnienia plików
Odczytuj i modyfikuj uprawnienia plików, własność, znaczniki czasu i rozmiary. Pełna obsługa bitów trybu w stylu Unix i dowiązań symbolicznych.
Postęp i zdarzenia
Śledź postęp transferu z przesłanymi bajtami i całkowitym rozmiarem. Anulowalne transfery. Zdarzenia błędu, połączenia i rozłączenia.

Szybki start — połącz się i pobierz plik

Minimalny przykład, który łączy się ze zdalnym serwerem, pobiera plik i rozłącza się.

var
  oSFTP: TIdSFTPClient;
begin
  oSFTP := TIdSFTPClient.Create(nil);
  Try
    oSFTP.Host := 'sftp.example.com';
    oSFTP.Port := 22;
    oSFTP.Authentication.Username := 'deploy';
    oSFTP.Authentication.Password := 'secret';
    oSFTP.Connect;
    // Download a file
    oSFTP.Get('/data/report.csv', 'C:\local\report.csv');
    oSFTP.Disconnect;
  Finally
    oSFTP.Free;
  End;
end;

Uwierzytelnianie

Komponent obsługuje trzy metody uwierzytelniania. Wszystkie trzy są domyślnie włączone — klient i serwer automatycznie negocjują najbardziej odpowiednią metodę.

Uwierzytelnianie hasłem

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

Uwierzytelnianie kluczem publicznym

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

Weryfikacja klucza hosta

Zweryfikuj tożsamość serwera, sprawdzając odcisk palca klucza hosta w zdarzeniu OnSSHHostKey.

oSFTP.OnSSHHostKey := OnHostKey;
procedure TForm1.OnHostKey(Sender: TObject;
  const aHostKeyType, aFingerprint: string;
  var aAction: TIdSSHHostKeyVerification);
begin
  // Verify fingerprint against known hosts
  if aFingerprint = 'SHA256:xyzABC123...' then
    aAction := sshHostKeyAccept
  else
    aAction := sshHostKeyReject;
end;

Operacje na plikach

Przesyłanie i pobieranie

// Upload a file
oSFTP.Put('C:\local\data.zip', '/uploads/data.zip');
// Download a file
oSFTP.Get('/reports/monthly.pdf', 'C:\local\monthly.pdf');
// Upload from a stream
oSFTP.Put(oMemoryStream, '/uploads/stream-data.bin');
// Download to a stream
oSFTP.Get('/data/export.csv', oFileStream);

Wygodne metody dla ciągów znaków

// Read a remote file into a string
vContent := oSFTP.GetFileAsString('/config/settings.json');
// Write a string to a remote file
oSFTP.PutFileFromString('{"key":"value"}', '/config/settings.json');

Usuwanie, zmiana nazwy i dowiązania symboliczne

// Delete a remote file
oSFTP.Delete('/tmp/old-file.log');
// Rename / move a file
oSFTP.Rename('/data/temp.csv', '/data/final.csv');
// Create a symbolic link
oSFTP.Symlink('/data/final.csv', '/data/latest.csv');

Operacje na katalogach

// List directory contents with full metadata
var
  oItems: TIdSFTPDirectoryItems;
  i: Integer;
begin
  oItems := oSFTP.ListDirectory('/data');
  for i := 0 to Length(oItems) - 1 do
    WriteLn(oItems[i].Filename + ' - ' +
      IntToStr(oItems[i].Attrs.Size) + ' bytes');
end;
// Create and remove directories
oSFTP.MakeDirectory('/data/archive/2026');
oSFTP.RemoveDirectory('/data/temp');
// Get current working directory
vPath := oSFTP.GetCurrentDirectory;
// Resolve a path (follows symlinks, resolves . and ..)
vRealPath := oSFTP.RealPath('../data/../data/./file.txt');

Atrybuty i informacje o pliku

// Check existence
if oSFTP.FileExists('/data/report.csv') then
  WriteLn('File found');
if oSFTP.DirectoryExists('/data/archive') then
  WriteLn('Directory exists');
// Get file size
vSize := oSFTP.FileSize('/data/report.csv');
// Get full attributes (size, permissions, timestamps, UID/GID)
var
  oAttrs: TIdSFTPFileAttributes;
begin
  oAttrs := oSFTP.Stat('/data/report.csv');
  WriteLn('Size: ' + IntToStr(oAttrs.Size));
  WriteLn('Permissions: ' + IntToStr(oAttrs.Permissions));
end;

Postęp transferu i anulowanie

Zdarzenie OnSFTPProgress jest wywoływane podczas każdego transferu pliku, zapewniając śledzenie w czasie rzeczywistym z możliwością anulowania w trakcie transferu.

oSFTP.OnSFTPProgress := OnProgress;
procedure TForm1.OnProgress(Sender: TObject;
  const aFilename: string;
  aTransferred, aTotal: Int64;
  var Cancel: Boolean);
begin
  ProgressBar1.Max := aTotal;
  ProgressBar1.Position := aTransferred;
  Label1.Caption := Format('%s: %d / %d bytes',
    [aFilename, aTransferred, aTotal]);
  // Set Cancel := True to abort the transfer
  Cancel := FUserCancelled;
end;

Konfiguracja algorytmów kryptograficznych

Komponent obsługuje nowoczesne standardy kryptograficzne. Domyślne ustawienia są bezpieczne, ale możesz dostosować negocjację algorytmów pod kątem wymogów zgodności lub interoperacyjności.

Kategoria Obsługiwane algorytmy
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
// Restrict to only the strongest algorithms
oSFTP.Algorithms.Ciphers := 'aes256-gcm@openssh.com'
		,aes256-ctr';
oSFTP.Algorithms.KexAlgorithms := 'curve25519-sha256';
oSFTP.Algorithms.MACs := 'hmac-sha2-256,hmac-sha2-512';

Kompletny przykład

Przykład gotowy do produkcji, który łączy się z uwierzytelnianiem kluczem publicznym, listuje katalog, pobiera plik ze śledzeniem postępu i obsługuje błędy.

uses
  IdSFTPClient, IdSSHClasses;
var
  oSFTP: TIdSFTPClient;
  oItems: TIdSFTPDirectoryItems;
  i: Integer;
begin
  oSFTP := TIdSFTPClient.Create(nil);
  Try
    // Connection
    oSFTP.Host := 'sftp.example.com';
    oSFTP.Port := 22;
    // Public key authentication
    oSFTP.Authentication.Username := 'deploy';
    oSFTP.Authentication.PrivateKeyFile := 'C:\keys\id_ed25519';
    // Events
    oSFTP.OnSFTPProgress := OnProgress;
    oSFTP.OnSFTPError := OnError;
    oSFTP.OnSSHHostKey := OnHostKey;
    // Connect
    oSFTP.Connect;
    // List remote directory
    oItems := oSFTP.ListDirectory('/data');
    for i := 0 to Length(oItems) - 1 do
      WriteLn(oItems[i].Filename);
    // Download file with progress
    oSFTP.Get('/data/backup.tar.gz', 'C:\backups\backup.tar.gz');
    // Disconnect
    oSFTP.Disconnect;
  Finally
    oSFTP.Free;
  End;
end;

Dokumentacja metod

Metoda Opis
GetPobiera plik na lokalną ścieżkę lub do TStream
PutPrzesyła plik z lokalnej ścieżki lub TStream
DeleteUsuwa zdalny plik
RenameZmienia nazwę lub przenosi zdalny plik
ListDirectoryListuje zawartość katalogu z metadanymi
MakeDirectoryTworzy zdalny katalog
Stat / LStatPobiera atrybuty pliku (z/bez rozwiązywania dowiązań symbolicznych)
FileExists / DirectoryExistsSprawdza, czy plik lub katalog istnieje
Symlink / ReadLinkTworzy lub odczytuje dowiązania symboliczne
GetFileAsString / PutFileFromStringWygodne metody oparte na ciągach znaków