cURL / Mailing Lists / curl-library / Single Mail

curl-library

RE: Authentication

From: Xiuping Hu <xhu_at_aventail.com>
Date: Thu, 19 Feb 2004 08:57:28 -0800

Hi Daniel,

Thanks for your message and help!

>
> On Wed, 11 Feb 2004, Xiuping Hu wrote:
>
> > [Xiuping Hu] This is the case if you provide a wrong credential through
> > proxy to backend.
> > 1, c --> p --> s GET ... with credential forwarded
> > 2. p <-- s 401 Unauthorized
> > WWW-Authenticate: NTLM
> > 3. p --> s GET ..
> > Authorization: NTLM <base64-encoded Type1 message>
> > 4. p <-- s 401 Access Denied..
> > WWW-Authenticate: NTLM..
> > 5. p --> s GET ..
> > Authorization: NTLM <base64-encoded Type1 message>
> > 4 <--> 5 endless loop.
>
> I think I've understood how the error appears. I have not understood the
> reason for it, and that's why I asked:
>
> Why isn't ntlm->state already at state NTLMSTATE_TYPE1 when the
> autorization header is set?
>
> The basic principle of the code is that if it has already set the NTLM
> state
> machine into state TYPE1, it should not get another "blank" NTLM header
> without it returning CURLNTLM_BAD from Curl_input_ntlm(). You additional
> comparison implied that the check wasn't enough. I'm therefore asking you
> how
> it comes it isn't enough.

[Xiuping Hu] This problem has been solved in Feb., 12 build.
>
>
> > > 2. How do you expect your fix to work with proxies? We store the
> > > autorization header in a different variable and it has different
> context...
>
> > [Xiuping Hu] This fix stops endless looping in this scenarios, and give
> the
> > backend the chance to fall back to directly send the auth page to
client.
> > But one thing I can not fix at this time, that is once client receive
> the
> > auth page directly from backend, and enter his/her credential, proxy
> still
> > have no way to get it, and continue using the proxy credential, so
> > eventually it fails. How can we fix this issue?
>
> I don't understand the situation. Can you show me a step-by-step list like
> before?
[Xiuping Hu]
[Xiuping Hu] The situation is that I have a proxy server (It is really not a
proxy server but just a server in the middle for security purpose, so I do
not set proxy in the curl setopt). The password for proxy and for back-end
server is different. Once the use authenticated to the proxy successfully,
the proxy try to forward the credential to the back-end server. It obviously
will be fail. At this time, the back-end send 401 Access Denied header, and
the form for re-authentication; The user type the correct credential. But
the curl still remembers the proxy's credential, it continually does the
NTLM for this credential, so it will try the maximum times until the
back-end stop sending prompt page.

Basic Auth is doing same thing if I forward the credential like this. The
header included two Authorization: Basic header, one id for the proxy ; and
one is for the back-end, like this:
=======================================================================
HOST : Downstream Server (xxx.xxx.com)
DATE : 19/Feb/2004 00:41:49.070108 +0000
PID : 5310
ACTION : write
-----------------------------------------------------------------------
0000: 47 45 54 20 2f 73 65 63-75 72 65 2f 69 6e 64 65 GET /secure/inde
0010: 78 2e 68 74 6d 6c 20 48-54 54 50 2f 31 2e 31 0d x.html HTTP/1.1.
0020: 0a 41 75 74 68 6f 72 69-7a 61 74 69 6f 6e 3a 20 .Authorization:
0030: 42 61 73 69 63 20 63 6d-39 76 64 44 6f 6d 65 57 Basic cm9vdDomeW
0040: 39 31 63 6d 51 77 5a 77-3d 3d 0d 0a 48 6f 73 74 91cmQwZw==..Host
... ...
01e0: 44 0d 0a 41 63 63 65 70-74 2d 4c 61 6e 67 75 61 D..Accept-Langua
01f0: 67 65 3a 20 65 6e 2d 75-73 2c 7a 68 2d 63 6e 3b ge: en-us,zh-cn;
0200: 71 3d 30 2e 35 0d 0a 41-75 74 68 6f 72 69 7a 61 q=0.5..Authoriza
0210: 74 69 6f 6e 3a 20 42 61-73 69 63 20 64 58 4e 6c tion: Basic dXNl
0220: 63 6a 45 36 64 58 4e 6c-63 6a 45 3d 0d 0a 55 73 cjE6dXNlcjE=..Us
0230: 65 72 2d 41 67 65 6e 74-3a 20 4d 6f 7a 69 6c 6c er-Agent: Mozill
0240: 61 2f 34 2e 30 20 28 63-6f 6d 70 61 74 69 62 6c a/4.0 (compatibl
0250: 65 3b 20 4d 53 49 45 20-36 2e 30 3b 20 57 69 6e e; MSIE 6.0; Win
0260: 64 6f 77 73 20 4e 54 20-35 2e 30 29 0d 0a 43 6f dows NT 5.0)..Co
0270: 6e 6e 65 63 74 69 6f 6e-3a 20 4b 65 65 70 2d 41 nnection: Keep-A
0280: 6c 69 76 65 0d 0a 0d 0a- live....
>
[Xiuping Hu] Notice that the curl has write two Authorization headers into
the same write to the back-end. The wrong one overwrite the right one, so
that back-end denied.

For NTLM, it is same situation, but it is harder to ready NTLM message. But
I trace down to the curl, the username/password is still the proxy one.

To make this work, I have changed curl dated Feb., 12, 2004, here is the
patch:

--- ../../curl-7.11.1-20040215/lib/http.c Tue Feb 10 03:00:03 2004
+++ http.c Mon Feb 16 02:07:58 2004
@@ -386,7 +386,10 @@
         if(CURLNTLM_BAD != ntlm)
           conn->newurl = strdup(data->change.url); /* clone string */
         else
+ {
           infof(data, "Authentication problem. Ignoring this.\n");
+ return CURLE_BAD_PASSWORD_ENTERED;
+ }
       }
       else
         if(data->state.authwant & CURLAUTH_NTLM)
@@ -401,7 +404,10 @@
           CURLdigest dig = CURLDIGEST_BAD;
 
           if(data->state.digest.nonce)
+ {
             infof(data, "Authentication problem. Ignoring this.\n");
+ return CURLE_BAD_PASSWORD_ENTERED;
+ }
           else
             dig = Curl_input_digest(conn, start);
           
@@ -430,6 +436,7 @@
              valid. */
           data->state.authavail = CURLAUTH_NONE;
           infof(data, "Authentication problem. Ignoring this.\n");
+ return CURLE_BAD_PASSWORD_ENTERED;
         }
         else if(data->state.authwant & CURLAUTH_BASIC) {
           data->state.authavail |= CURLAUTH_BASIC;

Beside this, I have forced the curl stop doing the auth forwarding once
failure or success in my application:

if(strstr(auth_header,"NTLM"))
        {
                curl_easy_setopt(m_curl, CURLOPT_HTTPAUTH,
(long)CURLAUTH_BASIC)
;
        }
        else if(strstr(auth_header,"Basic"))
        {
                curl_easy_setopt(m_curl, CURLOPT_USERPWD, NULL);
                curl_easy_setopt(m_curl, CURLOPT_HTTPAUTH,
(long)CURLAUTH_NTLM);
        }

This is not good to force the curl doing other auth message, but this can be
stop the curl continually doing the reauth for this connection. I wil we
have a interface that we can call to stop the curl sending these headers in
some condition.

BTW, Do we have a time schedule for 11.1 release?

Thanks,

  • application/octet-stream attachment: curl.diff
Received on 2004-02-19