📄 idsocksserver.pas
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ http://www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 11757: IdSocksServer.pas
{
Rev 1.14 5/30/2004 7:50:44 PM DSiders
Corrected case in ancestor for TIdCustomSocksServer.
}
{
{ Rev 1.13 2004.03.03 10:28:48 AM czhower
{ Removed warnings.
}
{
{ Rev 1.12 2004.02.03 5:44:24 PM czhower
{ Name changes
}
{
{ Rev 1.11 1/21/2004 4:03:44 PM JPMugaas
{ InitComponent
}
{
{ Rev 1.10 2003.10.21 9:13:14 PM czhower
{ Now compiles.
}
{
{ Rev 1.9 2003.10.12 7:23:52 PM czhower
{ Compile todos
}
{
{ Rev 1.8 9/19/2003 04:27:04 PM JPMugaas
{ Removed IdFTPServer so Indy can compile with Kudzu's new changes.
}
{
{ Rev 1.7 9/16/2003 11:59:16 PM JPMugaas
{ Should compile.
}
{
Rev 1.6 1/20/2003 1:15:38 PM BGooijen
Changed to TIdTCPServer / TIdCmdTCPServer classes
}
{
{ Rev 1.5 1/17/2003 07:10:54 PM JPMugaas
{ Now compiles under new framework.
}
{
{ Rev 1.4 1/9/2003 06:09:36 AM JPMugaas
{ Updated for IdContext API change.
}
{
{ Rev 1.3 1/8/2003 05:53:50 PM JPMugaas
{ Switched stuff to IdContext.
}
{
{ Rev 1.2 12-8-2002 18:08:56 BGooijen
{ Changed to use TIdIOHandlerStack for the .IPVersion
}
{
{ Rev 1.1 12/7/2002 06:43:26 PM JPMugaas
{ These should now compile except for Socks server. IPVersion has to be a
{ property someplace for that.
}
{
{ Rev 1.0 11/13/2002 08:01:18 AM JPMugaas
}
{*****************************************************************************}
{* IdSocksServer.pas *}
{*****************************************************************************}
{*===========================================================================*}
{* DESCRIPTION *}
{*****************************************************************************}
{* PROJECT : Indy 10 *}
{* AUTHOR : Bas Gooijen (bas_gooijen@yahoo.com) *}
{* MAINTAINER : Bas Gooijen *}
{*...........................................................................*}
{* DESCRIPTION *}
{* Indy SOCKS 4/5 Server *}
{* *}
{* QUICK NOTES: *}
{* Socks5 GSSAPI-authentication is NOT supported. *}
{* UDP ASSOCIATE is NOT supported *}
{*...........................................................................*}
{* HISTORY *}
{* DATE VERSION AUTHOR REASONS *}
{* *}
{* 19/05/2002 1.0 Bas Gooijen Initial start *}
{* 24/05/2002 1.0 Bas Gooijen Added socks 5 authentication *}
{* 08/06/2002 1.0 Bas Gooijen Revised code *}
{* 08/09/2002 1.0 Bas Gooijen Added Socks 5 IPv6 Support *}
{*****************************************************************************}
unit IdSocksServer;
interface
uses
Classes,
IdAssignedNumbers, IdYarn, IdContext,
IdException,
IdGlobal,
IdTCPConnection,
IdTCPServer;
const
IdSocksAuthNoAuthenticationRequired = 0;
IdSocksAuthGSSApi = 1;
IdSocksAuthUsernamePassword = 2;
IdSocksAuthNoAcceptableMethods = $FF;
IdSocksLoginSuccess = 0;
IdSocksLoginFailure = 1; // any value except 0
type
EIdSocksSvrException = class(EIdException);
EIdSocksSvrNotSupported = class(EIdSocksSvrException);
EIdSocksSvrInvalidLogin = class(EIdSocksSvrException);
EIdSocksSvrSocks5WrongATYP = class(EIdSocksSvrException);
EIdSocksSvrWrongSocksVer = class(EIdSocksSvrException);
EIdSocksSvrWrongSocksCmd = class(EIdSocksSvrException);
EIdSocksSvrAccessDenied = class(EIdSocksSvrException);
EIdSocksSvrUnexpectedClose = class(EIdSocksSvrException);
TIdSocksServerContext = class( TIdContext )
protected
// what needs to be stored...
fUser: string;
fPassword: string;
FSocksVersion: byte; // either 4 or 5, or 0 when version not known yet
public
constructor Create(
AConnection: TIdTCPConnection;
AYarn: TIdYarn;
AList: TThreadList = nil
); override;
destructor Destroy; override;
property Username: string read fUser write fUser;
property Password: string read fPassword write fPassword;
property SocksVersion: byte read FSocksVersion write FSocksVersion;
end;
TIdOnAuthenticate = procedure( AThread: TIdSocksServerContext; const AUsername, APassword: string; var AAuthenticated: boolean ) of object;
TIdOnBeforeConnect = procedure( AThread: TIdSocksServerContext; const AUserId: string; var AHost: string; var APort: integer; var AAllowed: boolean ) of object;
TIdOnBeforeBind = procedure( AThread: TIdSocksServerContext; const AUserId: string; var AHost: string; var APort: integer; var AAllowed: boolean ) of object;
TIdCustomSocksServer = class( TIdTCPServer )
private
protected
fSocks5NeedsAuthentication: boolean;
fAllowSocks4: boolean;
fAllowSocks5: boolean;
fOnAuthenticate: TIdOnAuthenticate;
fOnBeforeConnect: TIdOnBeforeConnect;
fOnBeforeBind: TIdOnBeforeBind;
function DoExecute( AThread: TIdContext ) : boolean; override;
procedure CommandConnect( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ; virtual; abstract; //
procedure CommandBind( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ; virtual; abstract; //
procedure DoAuthenticate( AThread: TIdSocksServerContext; const AUsername, APassword: string; var AAuthenticated: boolean ) ; virtual;
procedure DoBeforeConnectUser( AThread: TIdSocksServerContext; const AUserId: string; var AHost: string; var APort: integer; var AAllowed: boolean ) ; virtual;
procedure DoBeforeBind( AThread: TIdSocksServerContext; const AUserId: string; var AHost: string; var APort: integer; var AAllowed: boolean ) ; virtual;
procedure HandleConnectV4( AThread: TIdSocksServerContext; var ACommand: byte; var AUserId, AHost: string; var Aport: integer ) ; virtual;
procedure HandleConnectV5( AThread: TIdSocksServerContext; var ACommand: byte; var AUserId, AHost: string; var Aport: integer ) ; virtual;
procedure InitComponent; override;
public
destructor Destroy; override;
published
property DefaultPort default IdPORT_SOCKS;
property Socks5NeedsAuthentication: boolean read fSocks5NeedsAuthentication write fSocks5NeedsAuthentication;
property AllowSocks4: boolean read fAllowSocks4 write fAllowSocks4;
property AllowSocks5: boolean read fAllowSocks5 write fAllowSocks5;
property OnAuthenticate: TIdOnAuthenticate read fOnAuthenticate write fOnAuthenticate;
property OnBeforeConnect: TIdOnBeforeConnect read fOnBeforeConnect write fOnBeforeConnect;
property OnBeforeBind: TIdOnBeforeBind read fOnBeforeBind write fOnBeforeBind;
end;
TIdSocksServer = class( TIdCustomSocksServer )
protected
procedure CommandConnect( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ; override; //
procedure CommandBind( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ; override; //
public
published
end;
TIdOnCommandConnect = procedure( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) of object;
TIdOnCommandBind = procedure( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) of object;
TIdEventSocksServer = class( TIdCustomSocksServer )
private
protected
fOnCommandConnect: TIdOnCommandConnect;
fOnCommandBind: TIdOnCommandBind;
procedure CommandConnect( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ; override; //
procedure CommandBind( AThread: TIdSocksServerContext; AUserId, AHost: string; Aport: integer ) ; override; //
public
published
property OnCommandConnect: TIdOnCommandConnect read fOnCommandConnect write fOnCommandConnect;
property OnCommandBind: TIdOnCommandBind read fOnCommandBind write fOnCommandBind;
end;
implementation
uses
IdResourceStringsProtocols,
IdTcpClient,
IdSimpleServer,
IdIOHandlerStack,
IdStack,
IdGlobalProtocols,
SysUtils;
function ReadBufferEx( AFrom: TIdTCPConnection; var ABuffer; const AMaxSize: Integer; const ATimeOut: integer = 25 ) : integer;
begin
if ( AMaxSize > 0 ) and ( @ABuffer <> nil ) then begin
todo;
// if AFrom.IOHandler.Buffer.Size { from.CurrentReadBufferSize} < AMaxSize then
// begin
AFrom.IOHandler.CheckForDataOnSource(ATimeOut ) ;
// end;
todo;
// if AFrom.IOHandler.Buffer.Size { from.CurrentReadBufferSize} > AMaxSize then
// begin
// result := AMaxSize;
// end
// else
// begin
// result := AFrom.IOHandler.Buffer.Size {from.CurrentReadBufferSize};
// end;
// AFrom.IOHandler.ReadBuffer( ABuffer, result ) ;
// end
// else
// begin
// result := 0;
end;
Result := 0;
end;
function GetBufferSize( AFrom: TIdTCPConnection; const ATimeOut: integer = 25 ) : integer;
begin
AFrom.IOHandler.CheckForDataOnSource(ATimeOut ) ;
todo;
// result := AFrom.IOHandler.Buffer.Size {from.CurrentReadBufferSize};
Result := 0;
end;
procedure TransferData( const FromConn, ToConn: TIdTCPConnection ) ;
var
buff: array[0..4095] of char;
amount: integer;
begin
while FromConn.Connected and ToConn.Connected do
begin
amount := ReadBufferEx( FromConn, buff, sizeof( buff ) ) ;
if amount > 0 then
begin
todo;
// ToConn.IOHandler.WriteBuffer( buff, amount ) ;
end;
amount := ReadBufferEx( ToConn, buff, sizeof( buff ) ) ;
if amount > 0 then
begin
todo;
// FromConn.IOHandler.WriteBuffer( buff, amount ) ;
end;
end;
end;
procedure TIdCustomSocksServer.DoAuthenticate( AThread: TIdSocksServerContext; const AUsername, APassword: string; var AAuthenticated: boolean ) ;
begin
if assigned( OnAuthenticate ) then
begin
OnAuthenticate( AThread, AUsername, APassword, AAuthenticated ) ;
end;
end;
procedure TIdCustomSocksServer.DoBeforeConnectUser( AThread: TIdSocksServerContext; const AUserId: string; var AHost: string; var APort: integer; var AAllowed: boolean ) ;
begin
if assigned( OnBeforeConnect ) then
begin
OnBeforeConnect( AThread, AUserId, AHost, APort, AAllowed ) ;
end;
end;
procedure TIdCustomSocksServer.DoBeforeBind( AThread: TIdSocksServerContext; const AUserId: string; var AHost: string; var APort: integer; var AAllowed: boolean ) ;
begin
if assigned( OnBeforeBind ) then
begin
OnBeforeBind( AThread, AUserId, AHost, APort, AAllowed ) ;
end;
end;
procedure SendV5Response( AThread: TIdSocksServerContext; const AResponse: byte ) ;
begin
AThread.Connection.IOHandler.Write( #5 + chr( AResponse ) ) ;
end;
procedure TIdCustomSocksServer.HandleConnectV5( AThread: TIdSocksServerContext; var ACommand: byte; var AUserId, AHost: string; var Aport: integer ) ;
var
LLine: string;
LTyp: byte;
LSupportsAuth: boolean;
Lusername, Lpassword: string;
LValidLogin: boolean;
a: integer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -