Pisze serwer FTP przy pomocy Indy10 na podstawie tutoriala z neta:
http://www.devarticles.com/c/a/Delphi-Kylix/The-Implementation-of-an-FTP-Server/1/

Na razie mam coś takiego:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdFTPServer, IdFTPList, IdFTPListOutput, IdFTPServerContextBase,
  IdComponent;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FTPServerListDirectory(ASender: TIdFTPServerContext; const APath: string; ADirectoryListing: TIdFTPListOutput; const ACmd : String; const ASwitches : String);
    procedure FTPServerAfterUserLogin(ASender: TIdFTPServerContext);
    procedure FTPServerUserLogin(ASender: TIdFTPServerContext; const AUsername, APassword: string; var VAuthenticated: Boolean);
    procedure FTPServerStatus(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string);
    procedure FTPServerChangeDirectory(ASender: TIdFTPServerContext; var VDirectory: string);
  private
    FTPServer: TIdFTPServer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FTPServer := TIdFTPServer.Create(self);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FTPServer.DefaultPort:=StrToInt(Edit3.Text);
  FTPServer.Active := True;
  showmessage('Active');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  FTPServer.Active := false;
  close;
end;

procedure TForm1.FTPServerListDirectory(ASender: TIdFTPServerContext; const APath: string; ADirectoryListing: TIdFTPListOutput; const ACmd: string; const ASwitches: string);
var
  FTPItem: TIdFTPListItem;
  SR: TSearchRec;
  SRI: Integer;
begin
  ADirectoryListing.DirFormat :=  doWin32;
  SRI := FindFirst(ASender.HomeDir + APath + '.', faAnyFile - faHidden - faSysFile, SR);
  while SRI = 0 do
  begin
    FTPItem := ADirectoryListing.Add;
    FTPItem.FileName := SR.Name;
    FTPItem.Size := SR.Size;
    FTPItem.ModifiedDate := FileDateToDateTime(SR.Time);
    if Sr.Attr = faDirectory then FTPItem.ItemType := ditDirectory
    else FTPItem.ItemType := ditFile;
    SRi := FindNext(SR);
  end;
  FindClose(SR);
  SetCurrentDir(ASender.HomeDir + APath + '..');
end;

procedure TForm1.FTPServerAfterUserLogin(ASender:TIdFTPServerContext);
begin
  ASender.HomeDir:='c:';
end;

procedure TForm1.FTPServerUserLogin(ASender: TIdFTPServerContext; const AUsername: string; const APassword: string; var VAuthenticated: Boolean);
begin
  if (AUsername = edit1.Text) and (APassword = edit2.Text) then
  begin
    VAuthenticated:=True
  end
  else
  begin
    VAuthenticated := False;
  end;
end;

procedure TForm1.FTPServerStatus(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string);
begin
  memo1.lines.add(Astatustext);
end;

procedure TForm1.FTPServerChangeDirectory(ASender: TIdFTPServerContext; var VDirectory: string);
begin
  ASender.CurrentDir := VDirectory;
end;

end.

Kiedy próbuję się zalogować (przy pomocy programu SmartFTP) za pomocą odpowiednich passów dostaję taki log:

[21:00:32] SmartFTP v3.0.1022.44
[21:00:33] Resolving host name "localhost"
[21:00:33] Connecting to 127.0.0.1 Port: 990
[21:00:33] Connected to localhost.
[21:00:33] 220 Indy FTP Server ready.
[21:00:33] USER MyUsername
[21:00:33] 331 User name okay, need password.
[21:00:33] PASS (hidden)
[21:00:33] 530 Not logged in.
[21:00:33] Active Help: http://www.smartftp.com/support/kb/51
[21:00:33] QUIT
[21:00:33] 221 Goodbye.
[21:00:33] Connect failed. Waiting to retry (30s)...
[21:00:33] Server closed connection

Co jest źle??