clientthread.cpp
来自「著名的SecureBlackBox控件完整源码」· C++ 代码 · 共 549 行 · 第 1/2 页
CPP
549 行
//---------------------------------------------------------------------------
#pragma hdrstop
#include "ClientThread.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
TClientThread::TClientThread(const AnsiString AHost, int APort, const AnsiString Username, AnsiString Password,
int AForwardPort, const AnsiString ADestHost, int ADestPort, bool NoGUI)
: TThread(true)
{
// inherited Create(true);
// creating tunnel list object
FTunnelList = new TElSSHTunnelList(NULL);
// creating and setting up tunnel object
FTunnel = new TElLocalPortForwardSSHTunnel(NULL);
FTunnel->Port = AForwardPort;
FTunnel->ToHost = ADestHost;
FTunnel->ToPort = ADestPort;
FTunnel->TunnelList = FTunnelList;
FTunnel->OnOpen = TunnelOpen;
FTunnel->OnClose = TunnelClose;
FTunnel->OnError = TunnelError;
// creating and setting up SSH client object
FSSHClient = new TElSSHClient(NULL);
FSSHClient->UserName = Username;
FSSHClient->Password = Password;
FSSHClient->Versions = Sbsshcommon::TSSHVersions() <<sbSSH1 <<sbSSH2;
FSSHClient->TunnelList = FTunnelList;
FSSHClient->CloseIfNoActiveTunnels = false;
FSSHClient->OnKeyValidate = SSHClientKeyValidate;
FSSHClient->OnAuthenticationSuccess = SSHClientAuthSuccess;
FSSHClient->OnAuthenticationFailed = SSHClientAuthFailed;
FSSHClient->OnSend = SSHClientSend;
FSSHClient->OnReceive = SSHClientReceive;
FSSHClient->OnOpenConnection = SSHClientOpen;
FSSHClient->OnCloseConnection = SSHClientClose;
FSSHClient->OnError = SSHClientError;
FSSHClient->ThreadSafe = false;
// creating socket objects
FTCPClient = new TIdTCPClient(NULL);
FTCPClient->Host = AHost;
FTCPClient->Port = APort;
FTCPServer = new TIdTCPServer(NULL);
FTCPServer->DefaultPort = AForwardPort;
FTCPServer->OnConnect = TCPServerConnect;
FTCPServer->OnExecute = TCPServerExecute;
// creating channel list
FChannels = new TList;
FCS = new TCriticalSection;
FGuiCS = new TCriticalSection;
FNoGUI = NoGUI;
Resume();
}
//---------------------------------------------------------------------------
__fastcall TClientThread::~TClientThread()
{
delete FChannels;
delete FTCPClient;
delete FTCPServer;
delete FSSHClient;
delete FTunnel;
delete FTunnelList;
delete FCS;
delete FGuiCS;
// TThread::~TThread();
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::TunnelOpen(TObject* Sender, TElSSHTunnelConnection* TunnelConnection)
{
TConnection* Conn;
Log("SSH channel opened", false);
Conn = (TConnection*)(TunnelConnection->Data);
Conn->FChannel = TunnelConnection;
Conn->FOutState = ocsActive;
TunnelConnection->OnData = TunnelConnData;
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::TunnelClose(TObject* Sender, TElSSHTunnelConnection* TunnelConnection)
{
if (TunnelConnection->Data != NULL)
{
Log("SSH channel closed", false);
((TConnection*)(TunnelConnection->Data))->FOutState = ocsClosed;
TunnelConnection->Data = NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::TunnelError(TObject* Sender, int Error, void* Data)
{
Log((AnsiString)"SSH tunnel error " + IntToStr(Error), false);
((TConnection*)(Data))->FOutState = ocsClosed;
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::TunnelConnData(TObject* Sender, void* Buffer, int Size)
{
((TConnection*)(((TElSSHTunnelConnection*)(Sender))->Data))->WriteToSocketBuffer(Buffer, Size);
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientKeyValidate(TObject* Sender, TElSSHKey* ServerKey, bool &Validate)
{
Log((AnsiString)"Server key received (fingerprint=" + DigestToStr(ServerKey->FingerprintMD5) + ")", false);
Validate = true;
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientAuthSuccess(TObject* Sender)
{
Log("SSH authentication succeeded", false);
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientAuthFailed(TObject* Sender, int AuthenticationType)
{
Log((AnsiString)"SSH authentication type " + IntToStr(AuthenticationType) + " failed", true);
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientSend(TObject* Sender, void* Buffer, int Size)
{
try
{
FTCPClient->WriteBuffer(Buffer, Size, false);
}
catch(Exception &e)
{
FError = true;
}
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientReceive(TObject* Sender, void* Buffer, int MaxSize, int &Written)
{
try
{
Written = FTCPClient->Socket->Recv(Buffer, MaxSize);
}
catch(Exception &e)
{
Written = 0;
FError = true;
}
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientOpen(TObject* Sender)
{
Log("SSH connection established", false);
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientClose(TObject* Sender)
{
Log("SSH connection closed", false);
FError = true;
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::SSHClientError(TObject* Sender, int ErrorCode)
{
Log((AnsiString)"SSH protocol error " + IntToStr(ErrorCode), true);
FError = true;
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::TCPServerConnect(TIdPeerThread* AThread)
{
TConnection* Conn;
Log("Incoming connection accepted", false);
Conn = new TConnection;
Conn->FThread = AThread;
AThread->Data = (TObject*)Conn;
AThread->FreeOnTerminate = true;
AThread->OnTerminate = TCPServerThreadTerminate;
FCS->Acquire();
try
{
FTunnel->Open(Conn);
}
__finally
{
FCS->Release();
}
if (!FNoGUI)
{
FGuiCS->Acquire();
try
{
DoConnectionAdd(Conn);
}
__finally
{
FGuiCS->Release();
}
}
}
//---------------------------------------------------------------------------
void __fastcall TClientThread::TCPServerExecute(TIdPeerThread* AThread)
{
char Buf[4096];
int Read;
AnsiString S;
TConnection* Conn = (TConnection*)(AThread->Data);
if ((AThread->Connection != NULL) && (AThread->Connection->Socket != NULL) &&
(AThread->Connection->Socket->Binding != NULL))
{
Conn->FRemoteHost = AThread->Connection->Socket->Binding->PeerIP;
Conn->FRemotePort = AThread->Connection->Socket->Binding->PeerPort;
}
while ((!AThread->Terminated) && (!((Conn->FInState == icsClosed) && (Conn->FOutState == ocsClosed))))
{
// processing socket endpoint
if (Conn->FInState == icsActive)
{
if (AThread->Connection->Connected())
{
try
{
AThread->Connection->CheckForGracefulDisconnect();
AThread->Connection->CheckForDisconnect();
// reading data from socket connection
if (AThread->Connection->InputBuffer->Size > 0)
{
//S = AThread->Connection->CurrentReadBuffer();
S = AThread->Connection->InputBuffer->Extract(AThread->Connection->InputBuffer->Size);
if (S.Length() > 0)
Conn->WriteToChannelBuffer(S.c_str(), S.Length());
}
// writing cached data to socket connection
do
{
Read = Conn->ReadFromSocketBuffer(Buf, 4096);
if (Read > 0)
AThread->Connection->WriteBuffer(Buf, Read);
} while (Read == 0);
}
catch(Exception &e)
{
Log(e.Message, false);
Conn->FInState = icsClosing;
if ((AThread->Connection != NULL) &&
(AThread->Connection->Connected()) && (AThread->Connection->Socket != NULL) &&
(AThread->Connection->Socket->Binding != NULL))
AThread->Connection->Disconnect();
}
}
else
Conn->FInState = icsClosed;
}
// processing channel endpoint
if (Conn->FOutState == ocsActive)
{
do
{
Read = Conn->ReadFromChannelBuffer(Buf, 4096);
if (Read > 0)
{
FCS->Acquire();
try
{
Conn->FChannel->SendData(Buf, Read);
}
__finally
{
FCS->Release();
}
Conn->FSent += Read;
}
} while (Read == 0);
}
// checking connection states
if ((Conn->FInState == icsActive) && (Conn->FOutState == ocsClosed || Conn->FOutState == ocsClosing))
{
Conn->FInState = icsClosing;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?