【问题标题】:IndyTCP Socket Behaves unpredictablyIndyTCP 套接字行为不可预测
【发布时间】:2015-08-12 09:17:53
【问题描述】:

为什么这段代码的行为不可预测?

procedure ConnectToShell(ID: Integer; Password: String);
var
  cmd:String;
begin
  if (ID <> Length(ContextList) - 1)
  or (ContextList[ID].Context.Connection = nil) then
    writeln('This user not found')
  else begin
    ContextList[ID].Context.Connection.Socket.WriteLn('AUTH 1.0');
    Path := ContextList[ID].Context.Connection.Socket.ReadLnWait();
    if ContextList[ID].Context.Connection.Socket.ReadLnWait() = 'ADMIT' then
    begin
      ContextList[ID].Context.Connection.Socket.WriteLn(Password);
      if ContextList[ID].Context.Connection.Socket.ReadLnWait() = 'GRANTED' then
      begin
        ActiveU := ID;
        writeln('Access granted');  
      end else
        writeln('Access is denied');
    end else
      writeln('Access id denied');
  end;
end;

它的作用。这是来自服务器程序的代码。服务器侦听新客户端,并将它们的“上下文:IdContext”添加到 TUser 数组中。 TUser 是一条记录,包含三个字段:HostName、ID 和 Context。

在此代码程序中,尝试从数组“连接(授权)”到客户端。它需要 ID(数组中的索引)并发送命令“AUTH 1.0”,然后等待 Path(文件夹的路径)。之后,客户端必须发送“ADMIT”字样。之后,服务器发送一个密码,客户端检查它,如果一切正常,它必须发送“GRANTED”。

代替客户端,我在 Raw 模式下使用 Putty。 Putty 获得“AUTH 1.0”,我写道:
C:\
承认

我有一个问题。此时服务器没有发送密码,他在等我不知道是什么……但是如果我反复发送“ADMIT”,服务器仍然给我发送了密码。与“GRANTED”相同的故事。

【问题讨论】:

    标签: sockets delphi indy


    【解决方案1】:
      if (ID <> Length(ContextList) - 1)
    

    对于所有客户端都是如此,除了最后一个注册的客户端。 如果您有 100 个客户端,则仅允许其中的 99 号客户端通过,其余的将被拒绝。

    这是来自服务器程序的代码。

    是吗?那么客户端的代码在哪里?

    它监听新客户,并将他们的“上下文:IdContext”添加到 TUser 数组中

    不,它没有 - 修改 ContextList[ID] 数组的一行。


    基本上你所做的似乎是“被设计破坏”,那里有很多错误......

    1. 为什么服务器向客户端发送密码而不是客户端向服务器发送密码?你想达到什么目标?通常是服务器与客户端共享服务/资源,因此检查密码的是服务器,而不是客户端。您的软件群的总体方案是什么?您尝试解决什么任务以及如何解决?您的计划似乎没有意义,很难在其中找到错误。坐车的时候,只有知道自己要去哪里,才能检查路线是否有错误。我们只能看到很奇怪的路线,但我们不知道您的目的地,我们只能尝试猜测并指出常识。

    2. 密码不应该通过网络传递,它只是等待它们被任何 TCP 嗅探器拦截并被滥用。

    3. 服务器或客户端都可以知道密码。检查密码的一方应该不知道。

    4. 有一天,恶意客户端会发送 ID

    5. 有一天,一个流氓客户端每 10 秒会向您发送一封信,并且永远不会发送行尾。您的服务器将永远锁定在 Connection.Socket.ReadLnWait(); 内 - 您的系统已被最简单的 DoS 攻击冻结。

    这只是第一眼。

    很抱歉,我觉得(但我只能猜测,没有人知道你甚至试图实现什么)这段代码非常糟糕,最好将其转储并从头开始设计。这只是直觉,我可能错了。


    过程 ConnectToShell
    这是来自服务器程序的代码

    好吧,好吧,如果不是试图编写病毒,这将使控制服务器对受感染的客户端具有完全访问权限(“shell”),那么我想知道它是什么......

    【讨论】:

    • ContextList 是动态数组,它像 C++ 一样从 0 索引开始。如果 Length = 100 则数组将从 0 到 99。还有附加条件:如果 Connection != null (Connection established)
    • 哦,停下……我没听懂
    • 所以我对 dyn-array 的了解与您一样。好的。因此,对于 100 大小的 dyn-array,仅允许检查客户端 ID=99。其他用户将被立即丢弃。只会检查 Client-99 的额外条件,第一个条件将拒绝其他用户访问
    • 但是,顺便说一下,服务器和客户端之间的“对话”有问题
    • 截图higgs.rghost.ru/8FzQqTBJR/image.png 这是腻子控制台。在第二次“授予”之后,我在服务器控制台中获得了“访问权限”。但我想要,所以是:AUTH 1.0 ADMIT yummy GRANTED
    猜你喜欢
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2019-06-14
    • 1970-01-01
    • 2015-03-19
    相关资源
    最近更新 更多