📄 sbindysshclientiohandler9.pas
字号:
else
Result := false;
}
function CheckIsReadable(AMSec: Integer): Boolean;
begin
Result := false;
if not Assigned(FConnection) then
Exit;
Result := FInputBuffer.Size > 0;
if not Result then
begin
if AMSec = IdTimeoutDefault then
AMSec := ID_Default_TIdAntiFreezeBase_IdleTimeOut;
if AMSec = IdTimeoutInfinite then
begin
repeat
TIdAntiFreezeBase.Sleep(ID_Default_TIdAntiFreezeBase_IdleTimeOut);
if not Assigned(FConnection) then
Exit;
FTransport.FSSHClient.DataAvailable;
Result := FInputBuffer.Size > 0;
TIdAntiFreezeBase.DoProcess(Result = False);
until Result;
end
else
begin
TIdAntiFreezeBase.Sleep(AMSec);
FTransport.FSSHClient.DataAvailable;
Result := FInputBuffer.Size > 0;
TIdAntiFreezeBase.DoProcess(Result = False);
end;
end;
end;
begin
if TIdAntiFreezeBase.ShouldUse then
begin
if AMSec = IdTimeoutInfinite then
begin
repeat
Result := CheckIsReadable(GAntiFreeze.IdleTimeOut);
until Result;
Exit;
end
else
if AMSec > GAntiFreeze.IdleTimeOut then
begin
Result := CheckIsReadable(AMSec - GAntiFreeze.IdleTimeOut);
if Result then
begin
Exit;
end
else
begin
AMSec := GAntiFreeze.IdleTimeOut;
end;
end;
end;
Result := CheckIsReadable(AMSec);
end;
procedure TElClientIndySSHIOHandlerSocket.DoOnData(Sender: TObject;
Buffer: pointer; Size: Integer);
begin
FInputBuffer.Seek(0, soFromEnd);
FInputBuffer.Write(Buffer^, Size);
end;
procedure TElClientIndySSHIOHandlerSocket.DoOnClose(Sender: TObject;
CloseType: TSSHCloseType);
begin
FActive := false;
end;
procedure TElClientIndySSHIOHandlerSocket.DoOnError(Sender: TObject;
ErrorCode: integer);
begin
FErrorOccured := true;
end;
procedure TElClientIndySSHIOHandlerSocket.DoOnTunnelError(Sender: TObject;
ErrorCode: integer; Data: pointer);
var
IOHandler: TElClientIndySSHIOHandlerSocket;
begin
if Assigned(Data) and
(TObject(Data).ClassType = TElClientIndySSHIOHandlerSocket) then
begin
{ data is set to point to IOHandler, which handles this tunnel connection }
IOHandler := TElClientIndySSHIOHandlerSocket(Data);
IOHandler.FErrorOccured := true;
end
else
begin
{ data is not set - self is needed IOHandler }
FErrorOccured := true;
end;
end;
procedure TElClientIndySSHIOHandlerSocket.DoOnOpen(Sender: TObject;
TunnelConnection: TElSSHTunnelConnection);
var
IOHandler: TElClientIndySSHIOHandlerSocket;
begin
if Assigned(TunnelConnection.Data) and
(TObject(TunnelConnection.Data).ClassType = TElClientIndySSHIOHandlerSocket) then
begin
{ data is set to point to IOHandler, which handles this tunnel connection }
IOHandler := TElClientIndySSHIOHandlerSocket(TunnelConnection.Data);
TunnelConnection.OnClose := IOHandler.DoOnClose;
TunnelConnection.OnData := IOHandler.DoOnData;
TunnelConnection.OnError := IOHandler.DoOnError;
IOHandler.FConnection := TunnelConnection;
IOHandler.FActive := true;
end
else
begin
{ data is not set - self is needed IOHandler }
TunnelConnection.OnClose := DoOnClose;
TunnelConnection.OnData := DoOnData;
TunnelConnection.OnError := DoOnError;
FConnection := TunnelConnection;
FActive := true;
end;
end;
function TElClientIndySSHIOHandlerSocket.GetCommand: string;
begin
Command := '';
if Assigned(FTunnel) then
if FTunnelType = ttCommand then
Result := TElCommandSSHTunnel(FTunnel).Command;
end;
function TElClientIndySSHIOHandlerSocket.GetEnvironment: TStringList;
begin
Result := nil;
if Assigned(FTunnel) then
if FTunnelType = ttCommand then
Result := TElCommandSSHTunnel(FTunnel).Environment
else
if FTunnelType = ttShell then
Result := TElShellSSHTunnel(FTunnel).Environment
else
if FTunnelType = ttX11 then
Result := TElX11ForwardSSHTunnel(FTunnel).Environment;
end;
function TElClientIndySSHIOHandlerSocket.GetToHost: string;
begin
Result := '';
if Assigned(FTunnel) then
if FTunnelType = ttRemotePortToLocalAddress then
Result := TElRemotePortForwardSSHTunnel(FTunnel).ToHost
else
if FTunnelType = ttLocalPortToRemoteAddress then
Result := TElLocalPortForwardSSHTunnel(FTunnel).ToHost
end;
function TElClientIndySSHIOHandlerSocket.GetSubsystem: string;
begin
Result := '';
if Assigned(FTunnel) then
if FTunnelType = ttSubsystem then
Result := TElSubsystemSSHTunnel(FTunnel).Subsystem;
end;
function TElClientIndySSHIOHandlerSocket.GetTerminalInfo: TElTerminalInfo;
begin
Result := nil;
if Assigned(FTunnel) then
if FTunnelType = ttCommand then
Result := TElCommandSSHTunnel(FTunnel).TerminalInfo
else
if FTunnelType = ttShell then
Result := TElShellSSHTunnel(FTunnel).TerminalInfo
else
if FTunnelType = ttX11 then
Result := TElX11ForwardSSHTunnel(FTunnel).TerminalInfo;
end;
function TElClientIndySSHIOHandlerSocket.GetAuthenticationProtocol: string;
begin
Result := '';
if Assigned(FTunnel) then
if FTunnelType = ttX11 then
Result := TElX11ForwardSSHTunnel(FTunnel).AuthenticationProtocol;
end;
function TElClientIndySSHIOHandlerSocket.GetScreenNumber: integer;
begin
Result := -1;
if Assigned(FTunnel) then
if FTunnelType = ttX11 then
Result := TElX11ForwardSSHTunnel(FTunnel).ScreenNumber;
end;
function TElClientIndySSHIOHandlerSocket.GetToPort: integer;
begin
Result := 0;
if Assigned(FTunnel) then
if FTunnelType = ttLocalPortToRemoteAddress then
Result := TElRemotePortForwardSSHTunnel(FTunnel).ToPort
else
if FTunnelType = ttRemotePortToLocalAddress then
Result := TElLocalPortForwardSSHTunnel(FTunnel).ToPort;
end;
procedure TElClientIndySSHIOHandlerSocket.SetCommand(const Value: string);
begin
if Assigned(FTunnel) then
if FTunnelType = ttCommand then
TElCommandSSHTunnel(FTunnel).Command := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetSubsystem(
const Value: string);
begin
if Assigned(FTunnel) then
if FTunnelType = ttSubsystem then
TElSubsystemSSHTunnel(FTunnel).Subsystem := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetTerminalInfo(
const Value: TElTerminalInfo);
begin
if Assigned(FTunnel) then
if FTunnelType = ttCommand then
TElCommandSSHTunnel(FTunnel).TerminalInfo := Value
else
if FTunnelType = ttShell then
TElShellSSHTunnel(FTunnel).TerminalInfo := Value
else
if FTunnelType = ttX11 then
TElX11ForwardSSHTunnel(FTunnel).TerminalInfo := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetTransport(
const Value: TElClientIndySSHTransport);
begin
if Assigned(FTransport) then
raise EElIdSSHException.Create(SSSHTransportAlreadySet);
FTransport := Value;
FConnection := nil;
if FOwnTunnel then
begin
case FTunnelType of
ttLocalPortToRemoteAddress:
FTunnel := TElLocalPortForwardSSHTunnel.Create(nil);
ttRemotePortToLocalAddress:
FTunnel := TElRemotePortForwardSSHTunnel.Create(nil);
ttX11:
FTunnel := TElX11ForwardSSHTunnel.Create(nil);
ttAuthenticationAgent:
FTunnel := TElAuthenticationAgentSSHTunnel.Create(nil);
ttSubsystem:
FTunnel := TElSubsystemSSHTunnel.Create(nil);
ttCommand:
FTunnel := TElCommandSSHTunnel.Create(nil);
ttShell:
FTunnel := TElShellSSHTunnel.Create(nil);
end;
FTunnel.AutoOpen := false;
FTunnel.TunnelList := FTransport.FTunnelList;
FTunnel.OnOpen := DoOnOpen;
FTunnel.OnError := DoOnTunnelError;
end
else
FTunnel := nil;
end;
procedure TElClientIndySSHIOHandlerSocket.SetTunnelType(
const Value: TSSHTunnelType);
begin
if not Assigned(FTunnel) then
FTunnelType := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetToPort(const Value: integer);
begin
if Assigned(FTunnel) then
if FTunnelType = ttLocalPortToRemoteAddress then
TElRemotePortForwardSSHTunnel(FTunnel).ToPort := Value
else
if FTunnelType = ttRemotePortToLocalAddress then
TElLocalPortForwardSSHTunnel(FTunnel).ToPort := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetAuthenticationProtocol(
const Value: string);
begin
if Assigned(FTunnel) then
if FTunnelType = ttX11 then
TElX11ForwardSSHTunnel(FTunnel).AuthenticationProtocol := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetScreenNumber(
const Value: integer);
begin
if Assigned(FTunnel) then
if FTunnelType = ttX11 then
TElX11ForwardSSHTunnel(FTunnel).ScreenNumber := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetToHost(const Value: string);
begin
if Assigned(FTunnel) then
if FTunnelType = ttLocalPortToRemoteAddress then
TElRemotePortForwardSSHTunnel(FTunnel).ToHost := Value
else
if FTunnelType = ttRemotePortToLocalAddress then
TElLocalPortForwardSSHTunnel(FTunnel).ToHost := Value;
end;
procedure TElClientIndySSHIOHandlerSocket.SetTunnel(
const Value: TElCustomSSHTunnel);
begin
if (not FOwnTunnel) and (not Assigned(FTunnel)) and (Assigned(FTransport)) then
begin
FTunnel := Value;
FConnection := TElSSHClientTunnelConnection.Create;
FConnection.Tunnel := FTunnel;
FConnection.Data := Self;
FConnection.OnClose := DoOnClose;
FConnection.OnData := DoOnData;
FConnection.OnError := DoOnError;
FTunnel.AddConnection(FConnection);
end;
end;
procedure TElClientIndySSHIOHandlerSocket.SetOwnTunnel(
const Value: boolean);
begin
if not Assigned(FTunnel) then
FOwnTunnel := Value;
end;
{ TElClientIndySSHTransport }
constructor TElClientIndySSHTransport.Create(AOwner: TComponent);
begin
inherited;
FSSHClient := TElSSHClient.Create(nil);
FTunnelList := TElSSHTunnelList.Create(nil);
FSSHClient.TunnelList := FTunnelList;
FTCPClient := TIdTCPClient.Create(nil);
FTCPClient.OnDisconnected := DoTCPDisconnected;
FErrorOccured := false;
FOnAuthenticationSuccess := nil;
FOnAuthenticationFailed := nil;
FOnAuthenticationKeyboard := nil;
FOnBanner := nil;
FOnCloseConnection := nil;
FOnError := nil;
FOnKeyValidate := nil;
FActive := false;
FSSHClient.OnKeyValidate := DoSSHKeyValidate;
FSSHClient.OnAuthenticationSuccess := DoSSHAuthenticationSuccess;
FSSHClient.OnAuthenticationFailed := DoSSHAuthenticationFailed;
FSSHClient.OnAuthenticationKeyboard := DoSSHAuthenticationKeyboard;
FSSHClient.OnBanner := DoSSHBanner;
FSSHClient.OnSend := DoSSHSend;
FSSHClient.OnReceive := DoSSHReceive;
FSSHClient.OnCloseConnection := DoSSHCloseConnection;
FSSHClient.OnError := DoSSHError;
end;
procedure TElClientIndySSHTransport.Connect;
begin
try
FTCPClient.Connect;
if not FTCPClient.Connected then
raise EElIdNotImplementedException.Create(SCannotConnect);
FErrorOccured := false;
FActive := true;
FSSHClient.Open;
while FActive and (not FErrorOccured) and (not FSSHClient.Active) do
begin
FSSHClient.DataAvailable;
end;
if not FSSHClient.Active then
raise EElIdSSHException.Create(SCannotConnect);
except
on E: Exception do
begin
if FTCPClient.Connected then
begin
FTCPClient.InputBuffer.Clear;
FTCPClient.Disconnect;
end;
FActive := false;
FSSHClient.Close;
FErrorOccured := false;
raise;
end;
end;
end;
destructor TElClientIndySSHTransport.Destroy;
begin
if FActive then
Disconnect;
FreeAndNil(FSSHClient);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -