PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/indy/IdAuthentication.pas

https://code.google.com/
Pascal | 297 lines | 196 code | 47 blank | 54 comment | 14 complexity | 6890a4ae9c16ecb18044f9210c2bf531 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  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.5 10/26/2004 10:59:30 PM JPMugaas
  18. Updated ref.
  19. Rev 1.4 2004.02.03 5:44:52 PM czhower
  20. Name changes
  21. Rev 1.3 10/5/2003 5:01:34 PM GGrieve
  22. fix to compile Under DotNet
  23. Rev 1.2 10/4/2003 9:09:28 PM GGrieve
  24. DotNet fixes
  25. Rev 1.1 10/3/2003 11:40:38 PM GGrieve
  26. move InfyGetHostName here
  27. Rev 1.0 11/14/2002 02:12:52 PM JPMugaas
  28. 2001-Sep-11 : DSiders
  29. Corrected spelling for EIdAlreadyRegisteredAuthenticationMethod
  30. }
  31. unit IdAuthentication;
  32. {
  33. Implementation of the Basic authentication as specified in RFC 2616
  34. Copyright: (c) Chad Z. Hower and The Winshoes Working Group.
  35. Author: Doychin Bondzhev (doychin@dsoft-bg.com)
  36. }
  37. interface
  38. {$i IdCompilerDefines.inc}
  39. uses
  40. Classes,
  41. IdHeaderList,
  42. IdGlobal,
  43. IdException;
  44. type
  45. TIdAuthenticationSchemes = (asBasic, asDigest, asNTLM, asUnknown);
  46. TIdAuthSchemeSet = set of TIdAuthenticationSchemes;
  47. TIdAuthWhatsNext = (wnAskTheProgram, wnDoRequest, wnFail);
  48. TIdAuthentication = class(TPersistent)
  49. protected
  50. FCurrentStep: Integer;
  51. FParams: TIdHeaderList;
  52. FAuthParams: TIdHeaderList;
  53. function ReadAuthInfo(AuthName: String): String;
  54. function DoNext: TIdAuthWhatsNext; virtual; abstract;
  55. procedure SetAuthParams(AValue: TIdHeaderList);
  56. function GetPassword: String;
  57. function GetUserName: String;
  58. function GetSteps: Integer; virtual;
  59. procedure SetPassword(const Value: String); virtual;
  60. procedure SetUserName(const Value: String); virtual;
  61. public
  62. constructor Create; virtual;
  63. destructor Destroy; override;
  64. procedure Reset; virtual;
  65. procedure SetRequest(const AMethod, AUri: String); virtual;
  66. function Authentication: String; virtual; abstract;
  67. function KeepAlive: Boolean; virtual;
  68. function Next: TIdAuthWhatsNext;
  69. property AuthParams: TIdHeaderList read FAuthParams write SetAuthParams;
  70. property Params: TIdHeaderList read FParams;
  71. property Username: String read GetUserName write SetUserName;
  72. property Password: String read GetPassword write SetPassword;
  73. property Steps: Integer read GetSteps;
  74. property CurrentStep: Integer read FCurrentStep;
  75. end;
  76. TIdAuthenticationClass = class of TIdAuthentication;
  77. TIdBasicAuthentication = class(TIdAuthentication)
  78. protected
  79. FRealm: String;
  80. function DoNext: TIdAuthWhatsNext; override;
  81. function GetSteps: Integer; override; // this function determines the number of steps that this
  82. // Authtentication needs take to suceed;
  83. public
  84. function Authentication: String; override;
  85. property Realm: String read FRealm write FRealm;
  86. end;
  87. EIdAlreadyRegisteredAuthenticationMethod = class(EIdException);
  88. { Support functions }
  89. procedure RegisterAuthenticationMethod(const MethodName: String; const AuthClass: TIdAuthenticationClass);
  90. procedure UnregisterAuthenticationMethod(const MethodName: String);
  91. function FindAuthClass(const AuthName: String): TIdAuthenticationClass;
  92. implementation
  93. uses
  94. IdCoderMIME, IdGlobalProtocols, IdResourceStringsProtocols, SysUtils;
  95. var
  96. AuthList: TStringList = nil;
  97. procedure RegisterAuthenticationMethod(const MethodName: String; const AuthClass: TIdAuthenticationClass);
  98. var
  99. I: Integer;
  100. begin
  101. if not Assigned(AuthList) then begin
  102. AuthList := TStringList.Create;
  103. end;
  104. I := AuthList.IndexOf(MethodName);
  105. if I < 0 then begin
  106. AuthList.AddObject(MethodName, TObject(AuthClass));
  107. end else begin
  108. //raise EIdAlreadyRegisteredAuthenticationMethod.CreateFmt(RSHTTPAuthAlreadyRegistered, [AuthClass.ClassName]);
  109. AuthList.Objects[I] := TObject(AuthClass);
  110. end;
  111. end;
  112. procedure UnregisterAuthenticationMethod(const MethodName: String);
  113. var
  114. I: Integer;
  115. begin
  116. if Assigned(AuthList) then begin
  117. I := AuthList.IndexOf(MethodName);
  118. if I >= 0 then begin
  119. AuthList.Delete(I);
  120. end;
  121. end;
  122. end;
  123. function FindAuthClass(const AuthName: String): TIdAuthenticationClass;
  124. var
  125. I: Integer;
  126. begin
  127. I := AuthList.IndexOf(AuthName);
  128. if I > -1 then begin
  129. Result := TIdAuthenticationClass(AuthList.Objects[I]);
  130. end else begin
  131. Result := nil;
  132. end;
  133. end;
  134. { TIdAuthentication }
  135. constructor TIdAuthentication.Create;
  136. begin
  137. inherited Create;
  138. FAuthParams := TIdHeaderList.Create(QuoteHTTP);
  139. FParams := TIdHeaderList.Create(QuoteHTTP);
  140. FCurrentStep := 0;
  141. end;
  142. destructor TIdAuthentication.Destroy;
  143. begin
  144. FreeAndNil(FAuthParams);
  145. FreeAndNil(FParams);
  146. inherited Destroy;
  147. end;
  148. procedure TIdAuthentication.SetAuthParams(AValue: TIdHeaderList);
  149. begin
  150. FAuthParams.Assign(AValue);
  151. end;
  152. function TIdAuthentication.ReadAuthInfo(AuthName: String): String;
  153. Var
  154. i: Integer;
  155. begin
  156. for i := 0 to FAuthParams.Count - 1 do begin
  157. if TextStartsWith(FAuthParams[i], AuthName) then begin
  158. Result := FAuthParams[i];
  159. Exit;
  160. end;
  161. end;
  162. Result := ''; {Do not Localize}
  163. end;
  164. function TIdAuthentication.KeepAlive: Boolean;
  165. begin
  166. Result := False;
  167. end;
  168. function TIdAuthentication.Next: TIdAuthWhatsNext;
  169. begin
  170. Result := DoNext;
  171. end;
  172. procedure TIdAuthentication.Reset;
  173. begin
  174. FCurrentStep := 0;
  175. end;
  176. procedure TIdAuthentication.SetRequest(const AMethod, AUri: String);
  177. begin
  178. // empty here, descendants can override as needed...
  179. end;
  180. function TIdAuthentication.GetPassword: String;
  181. begin
  182. Result := Params.Values['Password']; {Do not Localize}
  183. end;
  184. function TIdAuthentication.GetUserName: String;
  185. begin
  186. Result := Params.Values['Username']; {Do not Localize}
  187. end;
  188. procedure TIdAuthentication.SetPassword(const Value: String);
  189. begin
  190. Params.Values['Password'] := Value; {Do not Localize}
  191. end;
  192. procedure TIdAuthentication.SetUserName(const Value: String);
  193. begin
  194. Params.Values['Username'] := Value; {Do not Localize}
  195. end;
  196. function TIdAuthentication.GetSteps: Integer;
  197. begin
  198. Result := 0;
  199. end;
  200. { TIdBasicAuthentication }
  201. function TIdBasicAuthentication.Authentication: String;
  202. begin
  203. with TIdEncoderMIME.Create do try
  204. Result := 'Basic ' + Encode(Username + ':' + Password); {do not localize}
  205. finally Free; end;
  206. end;
  207. function TIdBasicAuthentication.DoNext: TIdAuthWhatsNext;
  208. var
  209. S: String;
  210. begin
  211. S := ReadAuthInfo('Basic'); {Do not Localize}
  212. Fetch(S);
  213. while Length(S) > 0 do begin
  214. with Params do begin
  215. // realm have 'realm="SomeRealmValue"' format {Do not Localize}
  216. // FRealm never assigned without StringReplace
  217. Add(ReplaceOnlyFirst(Fetch(S, ', '), '=', NameValueSeparator)); {do not localize}
  218. end;
  219. end;
  220. FRealm := Copy(Params.Values['realm'], 2, Length(Params.Values['realm']) - 2); {Do not Localize}
  221. if FCurrentStep = 0 then
  222. begin
  223. if Length(Username) > 0 then begin
  224. Result := wnDoRequest;
  225. end else begin
  226. Result := wnAskTheProgram;
  227. end;
  228. end else begin
  229. Result := wnFail;
  230. end;
  231. end;
  232. function TIdBasicAuthentication.GetSteps: Integer;
  233. begin
  234. Result := 1;
  235. end;
  236. initialization
  237. RegisterAuthenticationMethod('Basic', TIdBasicAuthentication); {Do not Localize}
  238. finalization
  239. // UnregisterAuthenticationMethod('Basic') does not need to be called
  240. // in this case because AuthList is freed.
  241. FreeAndNil(AuthList);
  242. end.