IdIdent.pas 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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.6 2004.02.03 5:43:46 PM czhower
  18. Name changes
  19. Rev 1.5 1/21/2004 3:10:36 PM JPMugaas
  20. InitComponent
  21. Rev 1.4 3/27/2003 3:42:00 PM BGooijen
  22. Changed because some properties are moved to IOHandler
  23. Rev 1.3 2/24/2003 09:00:34 PM JPMugaas
  24. Rev 1.2 12/8/2002 07:25:18 PM JPMugaas
  25. Added published host and port properties.
  26. Rev 1.1 12/6/2002 05:30:00 PM JPMugaas
  27. Now decend from TIdTCPClientCustom instead of TIdTCPClient.
  28. Rev 1.0 11/13/2002 07:54:40 AM JPMugaas
  29. 2001 - Feb 12 - J. Peter Mugaas
  30. started this client
  31. }
  32. unit IdIdent;
  33. {
  34. This is the Ident client which is based on RFC 1413.
  35. }
  36. interface
  37. {$i IdCompilerDefines.inc}
  38. uses
  39. IdAssignedNumbers, IdException, IdTCPClient;
  40. const
  41. IdIdentQryTimeout = 60000;
  42. type
  43. TIdIdent = class(TIdTCPClientCustom)
  44. protected
  45. FQueryTimeOut : Integer;
  46. FReplyString : String;
  47. function GetReplyCharset: String;
  48. function GetReplyOS: String;
  49. function GetReplyOther: String;
  50. function GetReplyUserName: String;
  51. function FetchUserReply : String;
  52. function FetchOS : String;
  53. procedure ParseError;
  54. procedure InitComponent; override;
  55. public
  56. procedure Query(APortOnServer, APortOnClient : Word);
  57. property Reply : String read FReplyString;
  58. property ReplyCharset : String read GetReplyCharset;
  59. property ReplyOS : String read GetReplyOS;
  60. property ReplyOther : String read GetReplyOther;
  61. property ReplyUserName : String read GetReplyUserName;
  62. published
  63. property QueryTimeOut : Integer read FQueryTimeOut write FQueryTimeOut default IdIdentQryTimeout;
  64. property Port default IdPORT_AUTH;
  65. property Host;
  66. end;
  67. EIdIdentException = class(EIdException);
  68. EIdIdentReply = class(EIdIdentException);
  69. EIdIdentInvalidPort = class(EIdIdentReply);
  70. EIdIdentNoUser = class(EIdIdentReply);
  71. EIdIdentHiddenUser = class(EIdIdentReply);
  72. EIdIdentUnknownError = class(EIdIdentReply);
  73. EIdIdentQueryTimeOut = class(EIdIdentReply);
  74. implementation
  75. uses
  76. IdGlobal,
  77. IdGlobalProtocols,
  78. IdResourceStringsProtocols,
  79. SysUtils;
  80. const
  81. IdentErrorText : Array[0..3] of string = (
  82. 'INVALID-PORT', 'NO-USER', 'HIDDEN-USER', 'UNKNOWN-ERROR' {Do not Localize}
  83. );
  84. { TIdIdent }
  85. procedure TIdIdent.InitComponent;
  86. begin
  87. inherited InitComponent;
  88. FQueryTimeOut := IdIdentQryTimeout;
  89. Port := IdPORT_AUTH;
  90. end;
  91. function TIdIdent.FetchOS: String;
  92. var
  93. Buf : String;
  94. begin
  95. Buf := FetchUserReply;
  96. Result := Trim(Fetch(Buf,':')); {Do not Localize}
  97. end;
  98. function TIdIdent.FetchUserReply: String;
  99. var
  100. Buf : String;
  101. begin
  102. Result := ''; {Do not Localize}
  103. Buf := FReplyString;
  104. Fetch(Buf,':'); {Do not Localize}
  105. if TextIsSame(Trim(Fetch(Buf,':')), 'USERID') then begin {Do not Localize}
  106. Result := TrimLeft(Buf);
  107. end;
  108. end;
  109. function TIdIdent.GetReplyCharset: String;
  110. var
  111. Buf : String;
  112. begin
  113. Buf := FetchOS;
  114. if (Length(Buf) > 0) and (Pos(',', Buf) > 0) then begin {Do not Localize}
  115. Result := Trim(Fetch(Buf,',')); {Do not Localize}
  116. end else begin
  117. Result := 'US-ASCII'; {Do not Localize}
  118. end;
  119. end;
  120. function TIdIdent.GetReplyOS: String;
  121. var
  122. Buf : String;
  123. begin
  124. Buf := FetchOS;
  125. if Length(Buf) > 0 then begin
  126. Result := Trim(Fetch(Buf,',')); {Do not Localize}
  127. end else begin
  128. Result := ''; {Do not Localize}
  129. end;
  130. end;
  131. function TIdIdent.GetReplyOther: String;
  132. var
  133. Buf : String;
  134. begin
  135. if FetchOS = 'OTHER' then begin {Do not Localize}
  136. Buf := FetchUserReply;
  137. Fetch(Buf,':'); {Do not Localize}
  138. Result := TrimLeft(Buf);
  139. end;
  140. end;
  141. function TIdIdent.GetReplyUserName: String;
  142. var
  143. Buf : String;
  144. begin
  145. if FetchOS <> 'OTHER' then begin {Do not Localize}
  146. Buf := FetchUserReply;
  147. {OS ID}
  148. Fetch(Buf, ':'); {Do not Localize}
  149. Result := TrimLeft(Buf);
  150. end;
  151. end;
  152. procedure TIdIdent.ParseError;
  153. var
  154. Buf : String;
  155. begin
  156. Buf := FReplyString;
  157. Fetch(Buf, ':'); {Do not Localize}
  158. if Trim(Fetch(Buf, ':')) = 'ERROR' then begin {Do not Localize}
  159. case PosInStrArray(Trim(Buf), IdentErrorText, False) of
  160. {Invalid Port}
  161. 0 : Raise EIdIdentInvalidPort.Create(RSIdentInvalidPort);
  162. {No user}
  163. 1 : Raise EIdIdentNoUser.Create(RSIdentNoUser);
  164. {Hidden User}
  165. 2 : Raise EIdIdentHiddenUser.Create(RSIdentHiddenUser)
  166. else
  167. {Unknown or other error}
  168. raise EIdIdentUnknownError.Create(RSIdentUnknownError);
  169. end;
  170. end;
  171. end;
  172. procedure TIdIdent.Query(APortOnServer, APortOnClient: Word);
  173. var
  174. RTO : Boolean;
  175. begin
  176. FReplyString := ''; {Do not Localize}
  177. Connect;
  178. try
  179. WriteLn(IntToStr(APortOnServer) + ', ' + IntToStr(APortOnClient)); {Do not Localize}
  180. FReplyString := IOHandler.ReadLn('', FQueryTimeOut); {Do not Localize}
  181. {We check here and not return an exception at the moment so we can close our
  182. connection before raising our exception if the read timed out}
  183. RTO := IOHandler.ReadLnTimedOut;
  184. finally
  185. Disconnect;
  186. end;
  187. if RTO then begin
  188. raise EIdIdentQueryTimeOut.Create(RSIdentReplyTimeout);
  189. end;
  190. ParseError;
  191. end;
  192. end.