232 lines
6.4 KiB
Plaintext
232 lines
6.4 KiB
Plaintext
|
{
|
||
|
$Project$
|
||
|
$Workfile$
|
||
|
$Revision$
|
||
|
$DateUTC$
|
||
|
$Id$
|
||
|
|
||
|
This file is part of the Indy (Internet Direct) project, and is offered
|
||
|
under the dual-licensing agreement described on the Indy website.
|
||
|
(http://www.indyproject.org/)
|
||
|
|
||
|
Copyright:
|
||
|
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||
|
}
|
||
|
{
|
||
|
$Log$
|
||
|
}
|
||
|
{
|
||
|
Rev 1.13 12/2/2004 4:24:00 PM JPMugaas
|
||
|
Adjusted for changes in Core.
|
||
|
|
||
|
Rev 1.12 2004.02.03 5:44:32 PM czhower
|
||
|
Name changes
|
||
|
|
||
|
Rev 1.11 2004.01.22 2:33:58 PM czhower
|
||
|
Matched visibility of DoConnect
|
||
|
|
||
|
Rev 1.10 1/21/2004 4:20:52 PM JPMugaas
|
||
|
InitComponent
|
||
|
|
||
|
Rev 1.9 2003.10.21 9:13:16 PM czhower
|
||
|
Now compiles.
|
||
|
|
||
|
Rev 1.8 9/19/2003 04:27:02 PM JPMugaas
|
||
|
Removed IdFTPServer so Indy can compile with Kudzu's new changes.
|
||
|
|
||
|
Rev 1.7 7/6/2003 7:55:36 PM BGooijen
|
||
|
Removed unused units from the uses
|
||
|
|
||
|
Rev 1.6 2/24/2003 10:32:50 PM JPMugaas
|
||
|
|
||
|
Rev 1.5 1/17/2003 07:11:04 PM JPMugaas
|
||
|
Now compiles under new framework.
|
||
|
|
||
|
Rev 1.4 1/17/2003 04:05:40 PM JPMugaas
|
||
|
Now compiles under new design.
|
||
|
|
||
|
Rev 1.3 1/9/2003 06:09:42 AM JPMugaas
|
||
|
Updated for IdContext API change.
|
||
|
|
||
|
Rev 1.2 1/8/2003 05:53:58 PM JPMugaas
|
||
|
Switched stuff to IdContext.
|
||
|
|
||
|
Rev 1.1 12/7/2002 06:43:36 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:02:56 AM JPMugaas
|
||
|
}
|
||
|
|
||
|
unit IdTelnetServer;
|
||
|
|
||
|
interface
|
||
|
|
||
|
{$i IdCompilerDefines.inc}
|
||
|
|
||
|
uses
|
||
|
Classes,
|
||
|
IdGlobal,
|
||
|
IdBaseComponent,
|
||
|
IdAssignedNumbers, IdContext,
|
||
|
IdCustomTCPServer,
|
||
|
IdTCPConnection, IdYarn;
|
||
|
|
||
|
const
|
||
|
GLoginAttempts = 3;
|
||
|
|
||
|
type
|
||
|
|
||
|
// SG 16/02/2001: Moved the TTelnetData object from TIdPeerThread to custom TIdPeerThread descendant
|
||
|
|
||
|
TTelnetData = class(TObject)
|
||
|
public
|
||
|
Username, Password: String;
|
||
|
HUserToken: UInt32;
|
||
|
end;
|
||
|
|
||
|
// Custom Peer thread class
|
||
|
TIdTelnetServerContext = class(TIdServerContext)
|
||
|
private
|
||
|
FTelnetData: TTelnetData;
|
||
|
public
|
||
|
constructor Create(
|
||
|
AConnection: TIdTCPConnection;
|
||
|
AYarn: TIdYarn;
|
||
|
AList: TIdContextThreadList = nil
|
||
|
); override;
|
||
|
destructor Destroy; override;
|
||
|
Property TelnetData: TTelnetData read FTelnetData;
|
||
|
end; //class
|
||
|
|
||
|
|
||
|
TIdTelnetNegotiateEvent = procedure(AContext: TIdContext) of object;
|
||
|
TAuthenticationEvent = procedure(AContext: TIdContext;
|
||
|
const AUsername, APassword: string; var AAuthenticated: Boolean) of object;
|
||
|
|
||
|
TIdTelnetServer = class(TIdCustomTCPServer)
|
||
|
protected
|
||
|
FLoginAttempts: Integer;
|
||
|
FOnAuthentication: TAuthenticationEvent;
|
||
|
FLoginMessage: string;
|
||
|
FOnNegotiate: TIdTelnetNegotiateEvent;
|
||
|
//
|
||
|
procedure DoConnect(AContext: TIdContext); override;
|
||
|
procedure InitComponent; override;
|
||
|
public
|
||
|
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
|
||
|
constructor Create(AOwner: TComponent); reintroduce; overload;
|
||
|
{$ENDIF}
|
||
|
function DoAuthenticate(AContext: TIdContext; const AUsername, APassword: string)
|
||
|
: boolean; virtual;
|
||
|
procedure DoNegotiate(AContext: TIdContext); virtual;
|
||
|
published
|
||
|
property DefaultPort default IdPORT_TELNET;
|
||
|
property LoginAttempts: Integer read FLoginAttempts write FLoginAttempts Default GLoginAttempts;
|
||
|
property LoginMessage: String read FLoginMessage write FLoginMessage;
|
||
|
property OnAuthentication: TAuthenticationEvent read FOnAuthentication write FOnAuthentication;
|
||
|
property OnNegotiate: TIdTelnetNegotiateEvent read FOnNegotiate write FOnNegotiate;
|
||
|
property OnExecute;
|
||
|
end;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
uses
|
||
|
IdException, IdResourceStringsProtocols, SysUtils;
|
||
|
|
||
|
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
|
||
|
constructor TIdTelnetServer.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited Create(AOwner);
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
|
||
|
procedure TIdTelnetServer.InitComponent;
|
||
|
begin
|
||
|
inherited InitComponent;
|
||
|
LoginAttempts := GLoginAttempts;
|
||
|
LoginMessage := RSTELNETSRVWelcomeString;
|
||
|
DefaultPort := IdPORT_TELNET;
|
||
|
FContextClass := TIdTelnetServerContext;
|
||
|
end;
|
||
|
|
||
|
function TIdTelnetServer.DoAuthenticate;
|
||
|
begin
|
||
|
if not Assigned(OnAuthentication) then begin
|
||
|
raise EIdException.Create(RSTELNETSRVNoAuthHandler);
|
||
|
end;
|
||
|
Result := False;
|
||
|
OnAuthentication(AContext, AUsername, APassword, result);
|
||
|
end;
|
||
|
|
||
|
procedure TIdTelnetServer.DoConnect(AContext: TIdContext);
|
||
|
Var
|
||
|
Data: TTelnetData;
|
||
|
i: integer;
|
||
|
begin
|
||
|
try
|
||
|
inherited;
|
||
|
Data := (AContext as TIdTelnetServerContext).TelnetData;
|
||
|
// do protocol negotiation first
|
||
|
DoNegotiate(AContext);
|
||
|
// Welcome the user
|
||
|
if Length(LoginMessage) > 0 then
|
||
|
begin
|
||
|
AContext.Connection.IOHandler.WriteLn(LoginMessage);
|
||
|
AContext.Connection.IOHandler.WriteLn; {Do not Localize}
|
||
|
end;
|
||
|
// Only prompt for creditentials if there is an authentication handler
|
||
|
if Assigned(OnAuthentication) then
|
||
|
begin
|
||
|
// ask for username/password.
|
||
|
for i := 1 to LoginAttempts do
|
||
|
begin
|
||
|
// UserName
|
||
|
AContext.Connection.IOHandler.Write(RSTELNETSRVUsernamePrompt);
|
||
|
Data.Username := AContext.Connection.IOHandler.InputLn;
|
||
|
// Password
|
||
|
AContext.Connection.IOHandler.Write(RSTELNETSRVPasswordPrompt);
|
||
|
Data.Password := AContext.Connection.IOHandler.InputLn('*'); {Do not Localize}
|
||
|
AContext.Connection.IOHandler.WriteLn;
|
||
|
// Check authentication
|
||
|
if DoAuthenticate(AContext, Data.Username, Data.Password) then begin
|
||
|
Break; // exit the loop
|
||
|
end;
|
||
|
AContext.Connection.IOHandler.WriteLn(RSTELNETSRVInvalidLogin); // translate
|
||
|
if i = FLoginAttempts then begin
|
||
|
raise EIdException.Create(RSTELNETSRVMaxloginAttempt); // translate
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
except
|
||
|
on E: Exception do begin
|
||
|
AContext.Connection.IOHandler.WriteLn(E.Message);
|
||
|
AContext.Connection.Disconnect;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TIdTelnetServer.DoNegotiate(AContext: TIdContext);
|
||
|
begin
|
||
|
if Assigned(FOnNegotiate) then begin
|
||
|
FOnNegotiate(AContext);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
{ TIdTelnetServerContext }
|
||
|
|
||
|
constructor TIdTelnetServerContext.Create(AConnection: TIdTCPConnection;
|
||
|
AYarn: TIdYarn; AList: TIdContextThreadList = nil);
|
||
|
begin
|
||
|
inherited Create(AConnection, AYarn, AList);
|
||
|
FTelnetData := TTelnetData.Create;
|
||
|
end;
|
||
|
|
||
|
destructor TIdTelnetServerContext.Destroy;
|
||
|
begin
|
||
|
FreeAndNil(FTelnetData);
|
||
|
inherited Destroy;
|
||
|
end;
|
||
|
|
||
|
end.
|