EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Indy SSL IOHandler doesn't repect Timeout

Also by EldoS: CallbackRegistry
A component to monitor and control Windows registry access and create virtual registry keys.
#12100
Posted: 01/13/2010 11:49:33
by Nathan Sutcliffe (Standard support level)
Joined: 09/13/2006
Posts: 14

We're using SecureBlackBox version 5.1.112 with Indy 10.1.5 in Delphi 2007, connecting a TElClientIndySSLIOHandlerSocket to a TIdHTTP to an HTTPS post. Someone was doing some testing with an incorrect configuration and ended up trying to connect to what I think was a non-https server. Instead of timing out, the THTTPS.Post just hung.

It looks like in TElClientIndySSLIOHandlerSocket.StartSSL calls TIdSocketHandle.Select with the default timeout value of IdTimeoutInfinite, ignoring the timeout properties.

Do you know if this is fixed in the latest version of SecureBlackBox?
#12101
Posted: 01/13/2010 12:03:16
by Mykola Olshevsky (Basic support level)
Joined: 07/07/2005
Posts: 450

Hi. Yes, this issue was fixed. Version 5.1.112 is quite old.
#12103
Posted: 01/13/2010 12:23:13
by Nathan Sutcliffe (Standard support level)
Joined: 09/13/2006
Posts: 14

Thanks.
#14824
Posted: 10/27/2010 16:18:08
by Nathan Sutcliffe (Standard support level)
Joined: 09/13/2006
Posts: 14

Using version 8.0.176, the timeout isn't being respected properly. If I set ConnectTimeout to 5 seconds (5000), I'm getting a timeout error after 2 seconds in some situations.

I think the problem is the following line in TElClientServerIndySSLIOHandlerSocket.StartSSL:

Timeout := TimeLeft;

I don't think that line makes any sense.

Has this been fixed in the latest version? If so, I'll get my boss to download it.
#14827
Posted: 10/28/2010 01:11:00
by Eugene Mayevski (EldoS Corp.)

The code is valid and the assignment makes perfect sense if you study the code more attentively.

If you have a license, please assign the license ticket to your user account before we continue. The ticket itself and the procedure of it's use are specified in the registration e-mail that was sent to you upon license purchase.


Sincerely yours
Eugene Mayevski
#14849
Posted: 10/28/2010 11:08:40
by Nathan Sutcliffe (Standard support level)
Joined: 09/13/2006
Posts: 14

I'm attentively studying version 8.0.176 of the VCL code. I hope we're studying the same versions of TElClientServerIndySSLIOHandlerSocket.StartSSL.

Let's start with BeginAt := GetTickCount() and suppose it gets set to 10000.
Let's suppose Timeout = 1000.

The first time through the loop, let's suppose GetTickCount() returns 10100:
TimeLeft = 1000 - ( 10100 - 10000 ) = 900
Timeout = 900

Next time through the loop, let's suppose GetTickCount() returns 10200:
TimeLeft = 900 - ( 10200 - 10000 ) = 700
Timeout = 700

Next time through the loop, let's suppose GetTickCount() returns 10300:
TimeLeft = 700 - ( 10300 - 10000 ) = 400
Timeout = 400

Next time through the loop, let's suppose GetTickCount() returns 10400:
TimeLeft = 400 - ( 10400 - 10000 ) = 0
<Break>

A timeout was just reported after 400ms, even though the timeout was set to 1000ms.
#14850
Posted: 10/28/2010 11:25:27
by Eugene Mayevski (EldoS Corp.)

Thank you for calculation. After reading your post attentively I've seen that indeed there's some kind of mistake in timeout calculation (not obvious at all). We will fix it today or tomorrow and post the fix here.


Sincerely yours
Eugene Mayevski
#14852
Posted: 10/28/2010 11:29:34
by Eugene Mayevski (EldoS Corp.)

The quickest fix is

Code
procedure TElClientServerIndySSLIOHandlerSocket.StartSSL;
var
  BeginAt  : cardinal;
  Timeout  : integer;
  TimeLeft : integer;
  ToWait   : integer;
begin
  if FPassThrough then
    Exit;
  FErrorOccured := false;
  ForceClose := false;

  if FIsPeer then
  begin
    if FSecureServer.Active then
    begin
      FSecureServer.OnSend := nil;
      FSecureServer.Close;
    end;
    FSecureServer.OnSend := OnSecureClientSend;
    FSecureServer.OnReceive := OnSecureClientReceive;
    FSecureServer.OnData := OnSecureClientData;
    FSecureServer.Open;

    BeginAt := GetTickCount();
    Timeout := FConnectTimeout;

    if Timeout = IdTimeoutDefault then
      Timeout := FReadTimeOut;

    ToWait := Timeout;

    while (not FSecureServer.Active) and (not FErrorOccured) do
    begin
      if Assigned(FBinding) and FBinding.Select(ToWait) then
        FSecureServer.DataAvailable;

      if (Timeout >= 0) then
      begin
        TimeLeft := Timeout - Integer(TickDiff(BeginAt, GetTickCount()));
        if TimeLeft <= 0  then
          Break
        else
          ToWait := TimeLeft;
      end;
    end;
    if FSecureServer.Active then
    begin
      FSecured := true;
      DoSSLEstablished;
    end
    else
    begin
      ForceClose := true;
      raise EIdSSLProtocolReplyError.Create(RSSSLConnectError);
    end;
  end
  else
    inherited StartSSL;
end;


Should work fine. Please check and let me know.


Sincerely yours
Eugene Mayevski
#14853
Posted: 10/28/2010 13:15:27
by Nathan Sutcliffe (Standard support level)
Joined: 09/13/2006
Posts: 14

Thanks. We'll have to do some testing, but it looks like this will fix the problem.

BTW, it looks like there's similar code in:
TElClientIndySSLIOHandlerSocket.StartSSL
#14854
Posted: 10/28/2010 14:03:47
by Eugene Mayevski (EldoS Corp.)

Yes, I've changed it as well and checked other code where such mistake could appear. These seem to be the only ones. I guess it was some copy/paste error, as similar logic is used in many places, but there's minor difference between those places and this particular code.


Sincerely yours
Eugene Mayevski
Also by EldoS: MsgConnect
Cross-platform protocol-independent communication framework for building peer-to-peer and client-server applications and middleware components.

Reply

Statistics

Topic viewed 2637 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!