www.pudn.com > smtp_auth.zip > UnitSmtpLogin.pas


unit UnitSmtpLogin; 
 
interface 
 
uses NMSMTP,classes,Sysutils; 
 
type 
  EIdException = class(Exception); 
  TIdCardinalBytes = record 
    case Integer of 
    0: ( 
      Byte1: Byte; 
      Byte2: Byte; 
      Byte3: Byte; 
      Byte4: Byte;); 
    1: (Whole: Cardinal); 
  end; 
 
  function login(smtp:TNMSMTP;user,password:string):boolean; 
 
   
var 
  //MIME: 
  CodingTable: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 
  //UUE: CodingTable: string = '`!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_'; 
  //XXE: CodingTable: string = '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 
 
  //MIME: 
  FillChar: char = '='; 
  //UUE: CodingTable[1] or '~' 
  //XXE: CodingTable[1] or '~' 
 
implementation 
 
procedure EncodeUnit(const AIn1, AIn2, AIn3: Byte; var VOut: Cardinal); 
var 
  LUnit: TIdCardinalBytes; 
begin 
  LUnit.Byte1 := Ord(CodingTable[((AIn1 SHR 2) and 63) + 1]); 
  LUnit.Byte2 := Ord(CodingTable[(((AIn1 SHL 4) or (AIn2 SHR 4)) and 63) + 1]); 
  LUnit.Byte3 := Ord(CodingTable[(((AIn2 SHL 2) or (AIn3 SHR 6)) and 63) + 1]); 
  LUnit.Byte4 := Ord(CodingTable[(Ord(AIn3) and 63) + 1]); 
  VOut := LUnit.Whole; 
end; 
 
function Encode2(ASrcStream: TStream; const ABytes: integer = MaxInt): string; 
var 
  LIn1, LIn2, LIn3: Byte; 
  LSize: integer; 
  LStartPos: integer; 
  LUnit: TIdCardinalBytes; 
begin 
  //TODO: Make this more efficient. Profile it to test, but maybe make single calls to ReadBuffer 
  //then pull from memory 
  if (ABytes <> MaxInt) and ((ABytes mod 3) > 0) then begin 
    raise EIdException.Create('Uneven size in Encode.'); 
  end; 
  Result := ''; 
  LStartPos := ASrcStream.Position; 
  while (ASrcStream.Position < ASrcStream.Size) and (ASrcStream.Position - LStartPos < ABytes) 
   do begin 
    ASrcStream.ReadBuffer(LIn1, 1); 
    if ASrcStream.Position < ASrcStream.Size then begin 
      ASrcStream.ReadBuffer(LIn2, 1); 
      if ASrcStream.Position < ASrcStream.Size then begin 
        ASrcStream.ReadBuffer(LIn3, 1); 
        LSize := 3; 
      end else begin 
        LIn3 := 0; 
        LSize := 2; 
      end; 
    end else begin 
      LIn2 := 0; 
      LSize := 1; 
    end; 
    EncodeUnit(LIn1, LIn2, LIn3, LUnit.Whole); 
    Result := Result + Chr(LUnit.Byte1) + Chr(LUnit.Byte2) + Chr(LUnit.Byte3) + Chr(LUnit.Byte4); 
    if LSize < 3 then begin 
      Result[Length(Result)] := FillChar; 
      if LSize = 1 then begin 
        Result[Length(Result) - 1] := FillChar; 
      end; 
    end; 
  end; 
end; 
 
function Encode(const ASrc: string): string; 
var 
  LSrcStream: TStringStream; 
begin 
  LSrcStream := TStringStream.Create(ASrc); try 
    Result := Encode2(LSrcStream); 
  finally FreeAndNil(LSrcStream); end; 
end; 
 
function login(smtp:TNMSMTP;user,password:string):boolean; 
const crlf = #13#10; 
var 
   s:string; 
begin 
   result:=false; 
 try 
   s:='auth LOGIN'+crlf; 
   smtp.SendBuffer(pchar(s),length(s)); 
   s:=smtp.ReadLn; 
   if copy(s,1,3)<>'334' then exit;  //Fail 
 
   s:=Encode(user)+crlf; 
   smtp.SendBuffer(pchar(s),length(s)); 
   s:=copy(smtp.ReadLn,1,3); 
   if (s<>'334')and(s<>'235') then exit;  //Fail 
 
   s:=Encode(password)+crlf; 
   smtp.SendBuffer(pchar(s),length(s)); 
   s:=copy(smtp.ReadLn,1,3); 
   if (s<>'235') then exit;  //Fail 
   result:=true; 
 except 
 end; 
end; 
 
end.