Bug 1093348 - Kerberos authentication fails when server gives two 'WWW-Authenticate: Negotiate' headers
Summary: Kerberos authentication fails when server gives two 'WWW-Authenticate: Negoti...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: curl
Version: 20
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Kamil Dudka
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2014-05-01 13:42 UTC by David Woodhouse
Modified: 2014-05-26 23:58 UTC (History)
3 users (show)

Fixed In Version: curl-7.29.0-19.fc19
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2014-05-16 10:08:41 UTC


Attachments (Terms of Use)
http: avoid auth failure on a duplicated header [NOT TESTED] (1.79 KB, patch)
2014-05-05 12:57 UTC, Kamil Dudka
no flags Details | Diff

Description David Woodhouse 2014-05-01 13:42:37 UTC
We send an initial request, and we get back a response which looks like this:

HTTP/1.1 401 Unauthorized
server: IA Web Server
connection: close
content-type: text/html; charset=UTF-8
www-authenticate: Negotiate
www-authenticate: Negotiate
...

It looks like curl sees the first WWW-Authenticate: header and quite sanely calls gss_init_sec_context() once...

Breakpoint 1, gss_init_sec_context (minor_status=minor_status@entry=0x7fffffffd110, 
    claimant_cred_handle=claimant_cred_handle@entry=0x0, context_handle=context_handle@entry=0x634af8, target_name=0x813520, 
    req_mech_type=req_mech_type@entry=0x0, req_flags=6, time_req=time_req@entry=0, 
    input_chan_bindings=input_chan_bindings@entry=0x0, input_token=input_token@entry=0x7fffffffd120, 
    actual_mech_type=actual_mech_type@entry=0x0, output_token=output_token@entry=0x7fffffffd130, 
    ret_flags=ret_flags@entry=0x0, time_rec=time_rec@entry=0x0) at g_init_sec_context.c:113
113	{
(gdb) p *input_token
$2 = {length = 0, value = 0x0}
(gdb) fini
Run till exit from #0  gss_init_sec_context (minor_status=minor_status@entry=0x7fffffffd110, 
    claimant_cred_handle=claimant_cred_handle@entry=0x0, context_handle=context_handle@entry=0x634af8, target_name=0x813520, 
    req_mech_type=req_mech_type@entry=0x0, req_flags=6, time_req=time_req@entry=0, 
    input_chan_bindings=input_chan_bindings@entry=0x0, input_token=input_token@entry=0x7fffffffd120, 
    actual_mech_type=actual_mech_type@entry=0x0, output_token=output_token@entry=0x7fffffffd130, 
    ret_flags=ret_flags@entry=0x0, time_rec=time_rec@entry=0x0) at g_init_sec_context.c:113
Curl_gss_init_sec_context (data=data@entry=0x62c110, minor_status=minor_status@entry=0x7fffffffd110, 
    context=context@entry=0x634af8, target_name=<optimized out>, input_chan_bindings=input_chan_bindings@entry=0x0, 
    input_token=input_token@entry=0x7fffffffd120, output_token=output_token@entry=0x7fffffffd130, 
    ret_flags=ret_flags@entry=0x0) at curl_gssapi.c:67
67	}
Value returned is $3 = 1

It obtained a valid ticket for the corresponding HTTP service here, and generated a suitable token for sending to the HTTP server, returning GSS_S_CONTINUE_NEEDED.

(gdb) p *output_token
$5 = {length = 3671, value = 0x90f5b0}
(gdb) x/40xb 0x90f5b0
0x90f5b0:	0x60	0x82	0x0e	0x53	0x06	0x09	0x2a	0x86
0x90f5b8:	0x48	0x86	0xf7	0x12	0x01	0x02	0x02	0x01
0x90f5c0:	0x00	0x6e	0x82	0x0e	0x42	0x30	0x82	0x0e
0x90f5c8:	0x3e	0xa0	0x03	0x02	0x01	0x05	0xa1	0x03
0x90f5d0:	0x02	0x01	0x0e	0xa2	0x07	0x03	0x05	0x00

OK, so far so good... 

(gdb) c
Continuing.
< www-authenticate: Negotiate
www-authenticate: Negotiate

Breakpoint 1, gss_init_sec_context (minor_status=minor_status@entry=0x7fffffffd110, 
    claimant_cred_handle=claimant_cred_handle@entry=0x0, context_handle=context_handle@entry=0x634af8, target_name=0x813520, 
    req_mech_type=req_mech_type@entry=0x0, req_flags=6, time_req=time_req@entry=0, 
    input_chan_bindings=input_chan_bindings@entry=0x0, input_token=input_token@entry=0x7fffffffd120, 
    actual_mech_type=actual_mech_type@entry=0x0, output_token=output_token@entry=0x7fffffffd130, 
    ret_flags=ret_flags@entry=0x0, time_rec=time_rec@entry=0x0) at g_init_sec_context.c:113

Er, but now it hits the second WWW-Authenticate: header, still in the *first* (and only) HTTP response from the server. Invokes gss_init_sec_context() again, with the same context handle, and an empty input_token again.

(gdb) p *input_token
$6 = {length = 0, value = 0x0}
(gdb) fini
Run till exit from #0  gss_init_sec_context (minor_status=minor_status@entry=0x7fffffffd110, 
    claimant_cred_handle=claimant_cred_handle@entry=0x0, context_handle=context_handle@entry=0x634af8, target_name=0x813520, 
    req_mech_type=req_mech_type@entry=0x0, req_flags=6, time_req=time_req@entry=0, 
    input_chan_bindings=input_chan_bindings@entry=0x0, input_token=input_token@entry=0x7fffffffd120, 
    actual_mech_type=actual_mech_type@entry=0x0, output_token=output_token@entry=0x7fffffffd130, 
    ret_flags=ret_flags@entry=0x0, time_rec=time_rec@entry=0x0) at g_init_sec_context.c:113
Curl_gss_init_sec_context (data=data@entry=0x62c110, minor_status=minor_status@entry=0x7fffffffd110, 
    context=context@entry=0x634af8, target_name=<optimized out>, input_chan_bindings=input_chan_bindings@entry=0x0, 
    input_token=input_token@entry=0x7fffffffd120, output_token=output_token@entry=0x7fffffffd130, 
    ret_flags=ret_flags@entry=0x0) at curl_gssapi.c:67
67	}
Value returned is $7 = 589824
(gdb) p/x 589824
$8 = 0x90000

This time we get GSS_S_DEFECTIVE_TOKEN. It wasn't expecting an empty token now.

So we end up sending a further request to the server, with *no* Authentication: header. Get another response from the server with two 'WWW-Authenticate: Negotiate' headers, call gss_init_sec_context() for the same context another two times with empty input tokens, getting GSS_S_DEFECTIVE_TOKEN each time. And authentication fails.

Comment 1 David Woodhouse 2014-05-01 13:44:03 UTC
FWIW firefox also fails, now the server has started doing this. I don't actually think the server is wrong, is it? Just misguided, perhaps. I haven't debugged the firefox behaviour; curl was easier...

Comment 2 Kamil Dudka 2014-05-02 11:35:31 UTC
(In reply to David Woodhouse from comment #1)
> FWIW firefox also fails, now the server has started doing this. I don't
> actually think the server is wrong, is it?

If I understand it correctly, it is not curl's behavior what changed.  The server in question just started to send duplicated HTTP headers for no apparent reason.

I believe it makes sense to get curl ready for this.  We should probably also notify the maintainers of the server as the change seems to break many clients.

Comment 3 Kamil Dudka 2014-05-05 12:57:05 UTC
Created attachment 892526 [details]
http: avoid auth failure on a duplicated header [NOT TESTED]

Comment 4 Kamil Dudka 2014-05-05 12:58:06 UTC
David, could you please check whether the attached patch fixes the problem?

Comment 5 David Woodhouse 2014-05-08 14:25:42 UTC
Yes, that fixes it. Thanks.

(Firefox is *not* failing, btw. It did fail... and that's why I was looking with curl. But by the time I looked again, Firefox was working again and I don't know why it ever didn't).

Comment 6 Kamil Dudka 2014-05-09 05:38:43 UTC
Thanks you for testing the patch, David!  I have proposed the patch upstream:

http://thread.gmane.org/gmane.comp.web.curl.library/42368

Hopefully it was not a change on the server what made it work in both cases :-)

Comment 7 Kamil Dudka 2014-05-09 11:47:47 UTC
upstream commit:

https://github.com/bagder/curl/commit/ec5fde24

Comment 8 Kamil Dudka 2014-05-09 21:46:09 UTC
fixed in curl-7.36.0-4.fc21

Comment 9 Fedora Update System 2014-05-10 18:13:32 UTC
curl-7.29.0-19.fc19 has been submitted as an update for Fedora 19.
https://admin.fedoraproject.org/updates/curl-7.29.0-19.fc19

Comment 10 Fedora Update System 2014-05-10 18:13:45 UTC
curl-7.32.0-10.fc20 has been submitted as an update for Fedora 20.
https://admin.fedoraproject.org/updates/curl-7.32.0-10.fc20

Comment 11 Fedora Update System 2014-05-12 05:22:46 UTC
Package curl-7.32.0-10.fc20:
* should fix your issue,
* was pushed to the Fedora 20 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing curl-7.32.0-10.fc20'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/FEDORA-2014-6241/curl-7.32.0-10.fc20
then log in and leave karma (feedback).

Comment 12 Fedora Update System 2014-05-16 10:08:41 UTC
curl-7.32.0-10.fc20 has been pushed to the Fedora 20 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 13 Fedora Update System 2014-05-26 23:58:24 UTC
curl-7.29.0-19.fc19 has been pushed to the Fedora 19 stable repository.  If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.