Re: idHTTP with SSL and MS Proxy Server 2 with NTLM Authentication

Giganews Newsgroups
Subject: Re: idHTTP with SSL and MS Proxy Server 2 with NTLM Authentication
Posted by:  Christian (wtick…@yahoo.de)
Date: Tue, 04 Jan 2005

Hello Fabio

> Is there any known problem with NTLM authentication over MS Proxy
> Server 2?

I was struggling with the same problem, using indy 10.0.52. I'm not
experienced with indy and have no clue about the coding standards. Also
I have not tested enough to know, if there is any unwished side effects
with the following code changes - so do take care.

First the easy to fix problems:

In file "idAuthenticationNTLM.pas" the "FCurrentStep:=1" is at the wrong
place in the "DoNext" function. It should look like this:

function TIdNTLMAuthentication.DoNext: TIdAuthWhatsNext;
begin
  result := wnDoRequest;
  case FCurrentStep of
    0:
      begin
        if (Length(UserName) > 0) then
        begin
          result := wnDoRequest;
          FCurrentStep := 1;
        end
        else begin
          result := wnAskTheProgram;
        end;
        //FCurrentStep := 1;
      end;

---------------------------------------------------------
A bit odd, but I have verified with a network sniffer, that "LHost" must
be passed twice when calling "BuildType3Message":

function TIdNTLMAuthentication.Authentication: String;
...
  S := BuildType3Message(LHost, LHost, LUser, Password, Type2.Nonce);
...

---------------------------------------------------------
The next change must be done in the file "idHTTP.pas". It's really
unfortunate to see the nicely written indy code, getting messed up by
the adventurous "NTLM" authentication. During authentication process to
the proxy server, it will return "407" even if already in the middle of
the negotiation. Currently this reponsecode will clear the
username/password  in function "DoOnProxyAuthorization". This must be
prevented in case of NTLM-authentication.

  // Clear password and reset autorization if previous failed

  if (AResponse.FResponseCode = 407) then
  begin
    // only clear, if we don't deal with NTLM <-------
    if not AnsiSameText(
Copy(AResponse.RawHeaders.Values['Proxy-Authenticate'],1,4),'NTLM') then
    begin
      ProxyParams.ProxyPassword := '';
      ProxyParams.Authentication.Reset;
    end;
  end;

===========================================================

Now comes a problem which is not obvious for me to overcome.  Maybe you
or someone else can help?

The problem is, that currently no "Keep-alive"-connections are possible,
when using proxies and NTLM authentication can't work without. This is
because of a problem in the function "TIdCustomHTTP.SetHostAndPort".
Looking at the following code you can see that "LHost" is not
initialized and that it will always disconnect.

function TIdCustomHTTP.SetHostAndPort: TIdHTTPConnectionType;
var
  LHost: string;
  LPort: integer;
begin
  FPort := StrToIntDef(URL.Port, 80);
  FHost := URL.Host;
  LPort := Port;

  {
  Destination:= URL.Host+':'+URL.Port;
  Result := ctNormal;
  }
    // First check to see if a Proxy has been specified.
  if Length(ProxyParams.ProxyServer) > 0 then
  begin
    if ((not TextIsSame(LHost, ProxyParams.ProxyServer)) or
      (LPort <> ProxyParams.ProxyPort)) and (Connected) then
    begin
          Disconnect;
    end;
....

I have inserted "LHost:=Host" at the beginning of the function, but this
did not help. The "Host" variable is not set, when "SetHostandPort" is
called, if I remember right. However, this is the last problem to
overcome. If you comment out the "Disconnect" you will see that
NTLM-authentication works.
Currently I have no NTLM-proxy ready for testing and unfortunately also
no time. But in a couple of days I will try to investigate this closer
and I will post again, in case you have not solved it meanwhile.

For using NTLM authentication I did the following setup:
1. Added "idAuthenticationNTLM" to the uses clause.
2. Created the function:
procedure TidHttp.ProxyAuthorization(Sender: TObject; Authentication:
TIdAuthentication; var Handled: boolean);
begin
  Handled:=True;
end;
3. And initialized:
with idHttp do
begin
  ProtocolVersion := pv1_0;
  ProxyParams.BasicAuthentication :=False;
  ProxyParams.ProxyServer := 'proxyserver';
  ProxyParams.ProxyPort := 8080;
  ProxyParams.ProxyUsername:='domain\username';
  ProxyParams.ProxyPassword:='password';
  OnProxyAuthorization:=ProxyAuthorization;
end;

Kind regards
Christian Adler

Replies

In response to

idHTTP with SSL and MS Proxy Server 2 with NTLM Authentication posted by Fabio Dalle Ave on Wed, 29 Dec 2004