为什么这段代码表现不可预测?
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;
它做什么。这是来自服务器程序的代码。服务器侦听新客户端,并将其“Context:IdContext”添加到TUser数组中。 TUser是一个记录,包含三个字段:HostName,ID和Context。
在此代码程序中尝试从阵列“连接(授权)”到客户端。在等待Path(文件夹的路径)之后,它需要ID(数组中的索引)和发送命令“AUTH 1.0”。之后客户端必须发送“ADMIT”字样。之后,服务器发送了密码,客户端检查了它,如果一切正常,它必须发送“GRANTED”。
而不是客户端,我在原始模式下使用Putty。 Putty得到“AUTH 1.0”,我写道:
C:\
ADMIT
这里我有一个问题。在这一刻服务器没有发送密码,他等待我不知道是什么....但如果我反复发送“ADMIT”,服务器仍然给我发了一个密码。与“GRANTED”同样的故事。
答案 0 :(得分:0)
if (ID <> Length(ContextList) - 1)
除了单个客户端以外,所有客户端都是如此,最后一个客户端已注册。 如果你有100个客户,只允许其中99个客户端通过,其余客户将被拒绝。
是吗?那么来自客户的代码在哪里?这是来自服务器程序的代码。
它侦听新客户端,并将他们的“Context:IdContext”添加到TUser数组
不,它没有 - 修改 ContextList [ID]数组没有一行。
基本上你所做的似乎是“被设计破坏”,那里有很多错误......
为什么服务器向客户端发送密码而不是客户端发送密码?你试图实现什么?它通常是与客户端共享服务/资源的服务器,因此它是检查密码的服务器,而不是客户端。您的软件综合体的整体方案是什么?什么任务以及如何解决?你的计划似乎没有意义,因为它很难找到错误。当你在车上骑车时,如果你知道你去哪里,你只能检查路线是否没有错误。我们只能看到非常奇怪的路线,但我们不知道您的目的地,我们只能尝试猜测和指出常识。
密码不应该通过网络传递,只是等待它们被任何TCP嗅探器拦截并被滥用。
密码由服务器或客户端知道。检查密码的一方不应该知道它。
有一天,流氓客户端会发送ID&lt; 0,当它尝试读取数组外的数据时崩溃你的服务器。
有一天,一个流氓客户端会每10秒向您发送一个字母的数据,并且永远不会发送行尾。您的服务器将在Connection.Socket.ReadLnWait();
内被永久锁定 - 您的系统被最简单的DoS攻击冻结。
这只是乍一看。
很抱歉,我觉得(但我只能猜测,没有人知道你甚至试图实现什么)这个代码是如此破碎,最好从头开始倾倒和设计。这只是直觉,我可能是错的。
程序ConnectToShell
这是来自服务器程序的代码
嗯,好吧,如果不是尝试编写病毒,这会让控制服务器对受感染的客户端进行完全访问(“shell”),那么我想知道它是什么......