alex1818 / serf

Automatically exported from code.google.com/p/serf
Apache License 2.0
0 stars 0 forks source link

Support REAL SPNEGO authentication #89

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Right now, libserf claims to support SPNEGO authentication with GSS-API but it 
doesn't.

When initializing the GSS context, the OID of SPNEGO is not passed, instead 
NO_OID is passed thus MIT and Heimdal choose to perform Kerberos 5 which has a 
different OID.

I had the same dispute in libneon [1] so I am copying the RFC parts:

RFC4559 section 5 [2] says:

> The client will obtain the user credentials using the SPNEGO GSSAPI
> mechanism type to identify generate a GSSAPI message to be sent to
> the server with a new request, including the following Authorization
> header: [...]

More over RFC4178 section 3.2 makes the same statement about generated 
tokens/credentials:

> a) The GSS-API initiator invokes GSS_Init_sec_context() as normal,
>    but requests that SPNEGO be used.  SPNEGO can either be explicitly
>     requested or accepted as the default mechanism.

So, since SPNEGO OID is not passed and SPNEGO is not the default mech, serf 
behaves incorrectly.

I have attached a preliminary patch against 1.1.x which makes it work. The two 
attached screenshots depict the comm with a SPNEGO protected resource and the 
server happily answering libserf. As a mid-term goal, serf function names 
should be aligned to from serf__kerb_.. serf__spnego_.... Both mech could be 
easily added to serf_authn_schemes in auth.c. Since the code would be 
absolutely the same but the OID they could be called via a wrapper function 
passing the OID.

This issue is based on the discussion in 
http://subversion.tigris.org/issues/show_bug.cgi?id=3869

[1] http://lists.manyfish.co.uk/pipermail/neon/2012-June/001475.html
[2] http://tools.ietf.org/html/rfc4559#section-5

Original issue reported on code.google.com by 1983-01...@gmx.net on 22 Oct 2012 at 8:53

Attachments:

GoogleCodeExporter commented 9 years ago
Thx for the info, I should be able to look into it more closely in the coming 
days.

Selecting the SPNEGO mech instead of Kerberos in case of Negotiate makes sense, 
but a quick test shows that it breaks my test scenario. That's something I'll 
have to dig in tomorrow.
L.

Original comment by lieven.govaerts@gmail.com on 22 Oct 2012 at 11:01

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
What is you test scenario? Your acceptor has to pass SPNEGO_MECH to the 
gss_accept_sec_context too otherwise that impl is incomplete.

Original comment by 1983-01...@gmx.net on 23 Oct 2012 at 7:34

GoogleCodeExporter commented 9 years ago
I have made changes to serf trunk - including a modified version of your patch 
- which fix this issue for me.
The relevant revisions are r1669, r1671 and r1672.

Can you test serf trunk in your environment? Trunk has a different build system 
than serf 1.1.x, but for the rest it's compatible. Or you can merge the 
revisions to your serf 1.1.x copy. I'd like to get feedback first before I 
backport these revs.

FYI, my test env is:
- ubuntu 11.04, MIT Kerberos 5 release 1.8.3, apache 2.2.17 with mod_auth_kerb 
5.4-1
   Kerberos used both for proxy & svn modules (not at the same time)
- mac os x, MIT Kerberos 1.7.2, svn trunk, serf trunk

Original comment by lieven.govaerts@gmail.com on 23 Oct 2012 at 9:56

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Comment 6 by 1983-01...@gmx.net, Today (moments ago)

Changes look good, I will test trunk. I am fine with SCons since I have 
compiled serf 2.0.0-dev in the first place.

As far as I can see, mod_auth_kerb is still called "kerb" but still does SPNEGO 
correctly: 
http://modauthkerb.cvs.sourceforge.net/viewvc/modauthkerb/mod_auth_kerb/src/mod_
auth_kerb.c?view=markup#l1338 It sets up the correct gss_oid struct.

These are my test envs:
- Source 1: FreeBSD 8.3, Heimdal 1.1 (comes with the system)
- Source 2: RHEL 6, MIT Kerberos 1.9 (yum installed)
- Target 1: Microsoft ISA Proxy
- Target 2: Tomcat Java SPNEGO Authenticator (Java 6)
- Target 3: Microsoft IIS 7.5 on Windows Server 2008 R2

Give me a few days to recompile and test stuff.

Original comment by 1983-01...@gmx.net on 25 Oct 2012 at 12:19

GoogleCodeExporter commented 9 years ago
Tests are completed, patch works in the following combinations:

S1 => T1: works with and w/o SSL
S1 => T2: works with external pages and repos
S1 => T3: works with SSL, no unsecured server at hand
S2 => T1: works with and w/o SSL
S1 => T2: works with external pages and repos
S1 => T3: works with SSL, no unsecured server at hand

Tomcat server is in the same realm as I am but both MS servers are in different 
realms. Both setups work w/o a glitch.

PCAP files of all comm is available upon request. I would send them privately 
because I cannot diclose company's interal traffic.

I have found a few possible bugs where I do not know whether it is libserf or 
Subversion causing the bug.

Original comment by 1983-01...@gmx.net on 25 Oct 2012 at 1:07

GoogleCodeExporter commented 9 years ago
I am interested in seeing the pcap files. At least the headers + request lines 
of all requests + the headers of the responses, if you see a way to remove the 
message bodies I'm fine with that.

What I'm interested in is the behavior of the servers/proxies on the second 
request. Mod_auth_kerb requires authentication for each resource individually, 
so each individual request needs to be authenticated. That's not what serf does 
now. I can't find anything in the rfc's that documents how the 2nd, 3rd... 
requests on an authenticated connection needs to be handled, so I'm wondering 
if that's how all servers implement negotiate, or just mod_auth_kerb.

Original comment by lieven.govaerts@gmail.com on 27 Oct 2012 at 11:45

GoogleCodeExporter commented 9 years ago
Lieven, do you want to see the pcap files of the test setup or the possible 
bugs?
I would provide you the full pcap files for a full analysis via email on Monday 
if that's fine with you.

The way mod_auth_kerb implements auth is not specific to Negotiate. As you know 
HTTP is stateless. Every request is unique. If you request a resource you have 
to reauthenticate again. This is done in REST for example. The server might 
send you a session cookie or save your IP address to omit further auth for the 
next timeframe but that is server specific. This is done by our ISA proxy 
servers for example.

For instance, my Tomcat SPNEGO authenticator requires each and every request to 
be authenticated unless the webapp has created a session (same behavior as in 
any other authenticator in Tomcat), then the user principal is cached in the 
session and retrieved from there. You should monitor how Firefox performs Basic 
auth for example. It retrieves credentials from you and caches them. Any 
subseuquent response provides these cached credentials otherwise it would 
bother you on each and every request.

One bug I have observed is exactly the case you describe on subsequent 
requests. This is faulty. Subversion in trapped in an endless loop (issue 77).

Original comment by 1983-01...@gmx.net on 27 Oct 2012 at 12:12

GoogleCodeExporter commented 9 years ago
Both?

I know about http being stateless etc., but that doesn't exclude the 
possibility that both client and server cache an authenticated session per 
connection. I'm not inventing this btw, SPNEGO+NTLM is connection-oriented, so 
you're authenticating the connection via the first request, not authenticating 
access to individual resources. This + the fact that I can't find anywhere 
documented whether SPNEGO+Kerberos is stateless or not explains why I want to 
check how different server implementations handle this.

Original comment by lieven.govaerts@gmail.com on 27 Oct 2012 at 12:35

GoogleCodeExporter commented 9 years ago
Yes, you can have both sets of pcap files. The possible bugs need further 
annotation though.

The entire GSS-API, thus Kerberos + other challenge-response mech require a 
context/session to be held during communication and then released when comm is 
done. This is of course a contradiction the definition of HTTP.
Your indication is absolute correct, it the above scheme is applied to HTTP, 
the connection must be kept alive until all communcation has been completed.

From a client's POV this seems to be easy, since you use, say, one persistent 
connection per URL. 
How would that work actually on the server though? An authenticator has to know 
that this a persistent connection, save the GSS context in a app-wide hash map, 
authenticate the user and free the context when a "Connection: close" is 
issued. 
Several issues would arise:
1. How does the server notify the authenticator that a connection has be closed 
in a clean fashion or has been dropped due to network problems?
2. Connection timeouts, further notification possible.

You might end up in leaking memory by open GSS contexts which are not cleaned 
up correctly.

Thanks for making this clear, I definitively have to enquire this on the Tomcat 
mailing list. I am not able to retrieve that piece of information in my 
connector nor I was able to find anything useful in the Tomcat source code.
I guess this is the same situation in mod_auth_kerb.

Deducing from your statement, IIS and ISA proxy behave correctly.

These are nice refs: http://www.chromium.org/spdy/spdy-authentication and 
https://groups.google.com/forum/#!msg/spdy-dev/7Eb5jhaZBjc/A9wQFZfW-84J

Original comment by 1983-01...@gmx.net on 27 Oct 2012 at 1:28

GoogleCodeExporter commented 9 years ago
This one too: 
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html

Original comment by 1983-01...@gmx.net on 27 Oct 2012 at 1:31

GoogleCodeExporter commented 9 years ago
Message sent to Tomcat mailing list: 
http://www.mail-archive.com/users@tomcat.apache.org/msg102164.html

Original comment by 1983-01...@gmx.net on 27 Oct 2012 at 1:52

GoogleCodeExporter commented 9 years ago
There is good specification of spnego HTTP auth protocol my Microsoft:
http://msdn.microsoft.com/en-us/library/dd303576%28v=prot.20%29.aspx

Original comment by chemodax@gmail.com on 27 Oct 2012 at 3:29

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
chemodax, read that. What the hell is Nego2? There is a Persistent-Auth header 
mentioned for the connection. I believe I haven't seen it ever responding for 
an IIS 7.5 or ISA proxy server.
Does serf observe that? I guess not, neither does IE or FF. This header is 
specified as MAY.
RFC 4559 does not mention anything about that header + no explicit mention 
about stateful connections. This is weird.

Original comment by 1983-01...@gmx.net on 27 Oct 2012 at 3:58

GoogleCodeExporter commented 9 years ago
Lieven,

are you able to make a qualified comment on this issue? 
https://issues.apache.org/bugzilla/show_bug.cgi?id=54076

Original comment by 1983-01...@gmx.net on 4 Nov 2012 at 4:53

GoogleCodeExporter commented 9 years ago
It's clear that the expected authentication persistence behavior hasn't been 
documented in RFC 4559. Microsoft has implemented per-connection authentication 
in their products, whereas Tomcat and mod_auth_kerb have per-request 
authentication.

Also, HTTP 1.1 doesn't provide the headers to indicate how the server behaves 
in this respect:
- Keep-Alive isn't useful here, as 1) http/1.1 uses persistent connections by 
default and 2) the persistence here is about the authentication on the 
connection, not the connection itself.
- Connection:Close can be used to indicate connection closure, but that's again 
not indicating that the server uses persistent authentication. It's perfectly 
possible for a server to implement per-request authentication, but still allow 
multiple requests on the same connection.

In r1676 I've added support for both per-connection and per-request SPNEGO 
authentication. Server behavior is determined dynamically by sending the second 
request without Authenticate header and analyze the server's response to that.

Michael: can you test this with your multiple setups to see if you still see 
any issues?
Thanks for your efforts concerning this issues btw, your input has been most 
helpful!

Original comment by lieven.govaerts@gmail.com on 6 Nov 2012 at 10:20

GoogleCodeExporter commented 9 years ago
Lieven, yes please give me a few days to perform the tests. I guess I will have 
them by Monday.

I would like to test the entire setup with SSPI too but I have absolutely no 
clue how to compile serf, Subversion and dependent stuff on Windows. Are there 
any pointers, what would I need for?

Another note: Are you going to rename all filed *_kerb_* to *_spnego_* and 
provide *_krb5_* files which perform "WWW-Authenticate: Kerberos" too?

Original comment by 1983-01...@gmx.net on 7 Nov 2012 at 11:50

GoogleCodeExporter commented 9 years ago
I think we rename *_kerb_* to *_spnego_* someday. But I don't like idea to 
support both SPNEGO and Kerberos.

Original comment by chemodax@gmail.com on 7 Nov 2012 at 12:45

GoogleCodeExporter commented 9 years ago
Why not? This comes for free and you are save with both.

Lieven: Have you check mod_auth_sspi, it seems to have connection-level auth 
support: 
http://mod-auth-sspi.svn.sourceforge.net/viewvc/mod-auth-sspi/trunk/src/mod_auth
_sspi.c?revision=17&view=markup#l59

I so guess this must be possible with the Apache Web Server.

Original comment by 1983-01...@gmx.net on 7 Nov 2012 at 1:51

GoogleCodeExporter commented 9 years ago
It's not free. Managing multiple auth schemes for same thing is the real pain 
-- check neon code and you will see.

Original comment by chemodax@gmail.com on 7 Nov 2012 at 2:21

GoogleCodeExporter commented 9 years ago
Can you elaborate? It is actuall not the same thing. Kerberos and SPNEGO have 
different OIDs and different WWW-Authenticate values. Yes, the underlying code 
would be the sambe except for the context->mech value.

Original comment by 1983-01...@gmx.net on 7 Nov 2012 at 3:14

GoogleCodeExporter commented 9 years ago
I've implemented Windows SSPI part of fix in r1690.

I've only tested it against VisualSVN Server proprietary authentication module 
by patching serf to always use stateless authentication (VisualSVN Server uses 
statefull authentication)

If anyone interested I can provide statically linked svn.exe for Windows to 
test it against mod_auth_kerb. 

Original comment by chemodax@gmail.com on 9 Nov 2012 at 4:02

GoogleCodeExporter commented 9 years ago
Michael,

SPNEGO uses Kerberos inside, it's just a container for different auth 
protocols. And it doesn't makes sense to try Kerberos if SPNEGO credentials is 
not valid. I strongly suggest you to see neon code to feel the pain of 
supporting different kinds of multi-legged authentication in http library.

Original comment by chemodax@gmail.com on 9 Nov 2012 at 4:06

GoogleCodeExporter commented 9 years ago
chemodax, I can try your svn.exe if you like against our servers.
I was not talking about Kerberos as a fallback to SPNEGO. This would be silly. 
What I meant was being able to react on:

WWW-Authenticate: SPNEGO
WWW-Authenticate: Kerberos

If a server advertises either one, serf can serve either of them.

Multilegged auth contradicts the stateless model of HTTP. Especially NTLM which 
always requires several turnarounds. We are just lucky that SPNEGO/Kerberos 
completes after one turnaround.

Original comment by 1983-01...@gmx.net on 9 Nov 2012 at 4:56

GoogleCodeExporter commented 9 years ago
Michael,

I sent compiled svn.exe to @gmx.net mailbox.

Original comment by chemodax@gmail.com on 9 Nov 2012 at 5:34

GoogleCodeExporter commented 9 years ago
Evaluations on FreeBSD and Windows 7 have been mailed to Lieven on Monday.

Original comment by 1983-01...@gmx.net on 14 Nov 2012 at 8:41

GoogleCodeExporter commented 9 years ago
After several rounds of testing. GSS-API support with SPNEGO works very good 
now on *BSD and RHEL against Apache Tomcat, Microsoft IIS and Microsoft ISA 
Proxy.

SSPI is still buggy with Tomcat. We should focus on that in order to finish 
this ticket.

Original comment by 1983-01...@gmx.net on 3 Jan 2013 at 3:25

GoogleCodeExporter commented 9 years ago
The reported problem (using real SPNEGO) is fixed now. There are still some 
problems with SPNEGO authentication and HTTPS proxies, but they are tracked as 
separate issue 119. So closing this issue as Fixed.

Original comment by chemodax@gmail.com on 9 Aug 2013 at 4:51