⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbindysshclientiohandler9.pas

📁 著名的SecureBlackBox控件完整源码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  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 + -