IdSASLSKey.pas 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. Rev 1.4 2004.02.03 5:45:42 PM czhower
  18. Name changes
  19. Rev 1.3 1/25/2004 2:17:54 PM JPMugaas
  20. Should work better. Removed one GPF in S/Key.
  21. Rev 1.2 1/21/2004 4:03:18 PM JPMugaas
  22. InitComponent
  23. Rev 1.1 10/19/2003 5:57:20 PM DSiders
  24. Added localization comments.
  25. Rev 1.0 5/10/2003 10:08:14 PM JPMugaas
  26. SKEY SASL mechanism as defined in RFC 2222. Note that this is obsolete and
  27. you should use RFC 2444 for new designs. This is only provided for backwards
  28. compatibility.
  29. }
  30. unit IdSASLSKey;
  31. interface
  32. {$i IdCompilerDefines.inc}
  33. uses
  34. Classes,
  35. IdSASLUserPass, IdSASL;
  36. {
  37. S/KEY SASL mechanism based on RFC 2222.
  38. NOte that this is depreciated and S/Key is a trademark of BelCore. This unit
  39. is only provided for backwards compatiability with some older systems.
  40. New designs should use IdSASLOTP (RFC 2444) which is more flexible and uses a
  41. better hash (MD5 and SHA1).
  42. }
  43. type
  44. TIdSASLSKey = class(TIdSASLUserPass)
  45. public
  46. constructor Create(AOwner: TComponent); override;
  47. class function ServiceName: TIdSASLServiceName; override;
  48. function IsReadyToStart: Boolean; override;
  49. function TryStartAuthenticate(const AHost, AProtocolName : String; var VInitialResponse: String): Boolean; override;
  50. function StartAuthenticate(const AChallenge, AHost, AProtocolName : String) : String; override;
  51. function ContinueAuthenticate(const ALastResponse, AHost, AProtocolName : String): String; override;
  52. end;
  53. implementation
  54. uses
  55. IdFIPS, IdGlobal, IdGlobalProtocols, IdOTPCalculator, SysUtils;
  56. const
  57. SKEYSERVICENAME = 'SKEY'; {do not localize}
  58. { TIdSASLSKey }
  59. constructor TIdSASLSKey.Create(AOwner: TComponent);
  60. begin
  61. inherited Create(AOwner);
  62. //less than 1000 because MD4 is broken and this is depreciated
  63. FSecurityLevel := 900;
  64. end;
  65. function TIdSASLSKey.ContinueAuthenticate(const ALastResponse, AHost, AProtocolName : String): String;
  66. var
  67. LBuf, LSeed : String;
  68. LCount : UInt32;
  69. begin
  70. // RLebeau 4/17/2018: TIdSMTP calls TIdSASLEntries.LoginSASL() with ACanAttemptIR=True,
  71. // so the Username will be sent in the AUTH command's optional Initial-Response parameter.
  72. // Most SMTP servers support Initial-Response, but some do not, and unfortunately there
  73. // is no server advertisement for Initial-Response support defined for SMTP (unlike in
  74. // other protocols). If the server does not reject the AUTH command, but does not support
  75. // Initial-Response, the initial prompt will be for the username, not the password.
  76. // However, LoginSASL() will have already moved on from the initial step, and will call
  77. // ContinueAuthenticate() instead of StartAuthenticate(), so we need to handle both prompts
  78. // here ...
  79. if IsNumeric(ALastResponse, 1) then begin // the usual case, so check it first...
  80. LBuf := Trim(ALastResponse);
  81. LCount := IndyStrToInt(Fetch(LBuf), 0);
  82. LSeed := Fetch(LBuf);
  83. Result := TIdOTPCalculator.GenerateSixWordKey('md4', LSeed, GetPassword, LCount); {do not localize}
  84. end else begin // if the Initial-Response is ignored
  85. Result := StartAuthenticate(ALastResponse, AHost, AProtocolName);
  86. end;
  87. end;
  88. function TIdSASLSKey.IsReadyToStart: Boolean;
  89. begin
  90. Result := not GetFIPSMode;
  91. end;
  92. class function TIdSASLSKey.ServiceName: TIdSASLServiceName;
  93. begin
  94. Result := SKEYSERVICENAME;
  95. end;
  96. function TIdSASLSKey.TryStartAuthenticate(const AHost, AProtocolName : String;
  97. var VInitialResponse: String): Boolean;
  98. begin
  99. VInitialResponse := GetUsername;
  100. Result := True;
  101. end;
  102. function TIdSASLSKey.StartAuthenticate(const AChallenge, AHost, AProtocolName : String): String;
  103. begin
  104. Result := GetUsername;
  105. end;
  106. end.