Closed Bug 302209 Opened 19 years ago Closed 19 years ago

enable use of gssapi32.dll on windows

Categories

(Core :: Networking, defect)

x86
Windows XP
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: Bienvenu, Assigned: Bienvenu)

References

Details

(Keywords: fixed1.8)

Attachments

(2 files, 2 obsolete files)

A bit of history first: I've been trying to add gssapi authentication support to mailnews (imap/pop3/smtp), with an MIT Kerberos distribution. The server advertises AUTH=GSSAPI. Darin suggested trying the negotiate auth module. I plugged nsIAuthModule calls into the core mailnews protocol code and the imap code. I develop on Windows, so the negotiate auth module uses SSPI. That didn't work with the MIT Kerberos distribution, though perhaps I needed to extend the way we were using SSPI (if you have any info on that, cneberg, it would be very useful). In any case, I decided to try to add the ability to optionally use GSSAPI32.dll on Windows, if it was present. I hacked the make file a bit and tweaked nsNegotiateAuthGSSAPI.cpp so that it used the __stdcall calling convention on Windows. Simon Wilkinson tweaked the same file so that if a user name was passed in, it would do SASL instead of negoitate auth. The comment in the patch says // We've completed the GSSAPI portion of the handshake, and are // now ready to do the SASL security layer and authzid negotiation I'll attach the patch so you can see what's going on. Darin wanted me to run all this by you, cneberg, and your input would be greatly appreciated. I'm a total neophyte in this area. My plan is to do the following: 1.Add to cvs our own stand-alone version of gssapi.h, provided by Douglas Engert, so that we don't need to use the system one. 2. Remove the configure.in grief we go through to find gssapi.h 3. Build nsNegotiateAuthGSSAPI.cpp on windows (I'll need to rename the nsNegotiateAuth class in either or both of nsNegotiateAuthGSSAPI.cpp and nsNegotiateAuthSSPI.cpp, and add a custom constructor that chooses the right one based on the platform. 4. Add a component to nsNegotiateAuthFactory for gssapi, which would construct the nsNegotiateAuth in nsNegotiateAuthGSSAPI.cpp with an arg to the constructor to tell it to do gssapi/sasl. The contractId would be NS_AUTH_MODULE_CONTRACTID_PREFIX "gssapi". If it's possible to use SSPI to do auth=GSSAPI, then I'll need the factory to dynamically detect if gssapi32.dll is installed, at least on windows. 5.Add support for gssapi/sasl in nsNegotiateAuthGSSAPI.cpp 6. Use NS_AUTH_MODULE_CONTRACTID_PREFIX "gssapi" in the imap/pop3/smtp code.
This is just to show what what was done to nsNegotiateAuthGSSAPI to do SASL/GSSAPI. I'm looking for feedback on the basic approach. As I said, I would clean this up to allow the constructor to determine if we're doing sasl, instead of checking if there's a username. If you think this should be broken into a different .cpp file as well, with some shared code, that's an other option.
Cool. The SASL Gssapi code was one of the areas I was wanting to help investigate next. I've been working on Bug 280792 which overlaps with this one, but without the SASL slant. I've been working on a patch which attempts to do item 3 on your list so gssapi.dll and sspi can both be around on windows. I'll probably have a chance to post it here tomorrow.
Great, thx, Christopher. I'll wait for your patch before proceeding since there might be conflicts. I'll attach the standalone gssapi.h, though perhaps you have your own?
Firstly, some comments on the SSPI/MIT Kerberos For Windows issue. As far as I'm aware, SSPI can only deal with initial credentials obtained at login by machines which are members of an Active Directory realm. If you're using Leash32 (MIT's credentials manager), then SSPI will never see the credentials that it obtains. If you want to do Kerberos authentication using credentials in the MIT credcache, you have to use the MIT Kerberos implementation. However, MIT Kerberos can use credentials which were obtained by SSPI. All in all - MIT's implementation is more flexible, but does require additional libraries to be installed on the machine. If you're getting in to interface redefinition, it would be really good to have the following: *) A way of constraining the mechanism OIDs which are attempted. The SASL 'GSSAPI' name is confusing - it actually only applies to using the Kerberos mechanism. If you're doing SPENGO, then your mechanism name should be GSS-SPNEGO. It would be good to allow the calling function to control this, according to which SASL mechanism they're offering. This will be an issue when using SSPI. *) A way of NextToken indicating that authentication negotiation is complete. At the moment the only way for the client to tell that its authenticated is to wait for the server's response. As I said to David when I sent him the patch, the code is really the bare minimum to get SASL working - I tried to make the changes have as little general impact as possible.
We hadn't talked about changing interfaces, just the implementations, and the contract id's that are used to create the appropriate object that implements the nsIAuthModule interface. In any case, I don't know how Darin feels about changing nsIAuthModule - it's not frozen, so I guess it's technically possible. So the GetNextToken implementation knows whether further round trips are needed, w/o having to parse the data that comes back from the server?
Ah. Ok. Yes - gss_init_sec_context's return value indicates whether the connection is complete (by returning GSS_S_COMPLETE), or if further packets are expected from the server (GSS_S_CONTINUE_NEEDED). In the SASL case, the context is complete one round trip after the GSS handshake is completed. So NextToken can tell with each packet whether its the final one of the handshake or not - it just doesn't share that information with the rest of the world.
It should be easy enough to invent a success code that can be used to convey addition state from GetNextToken.
Darin, you mean roll it up in the return value so we don't have to change the interface? That's OK with me...
yes. we could use return codes (nsresult values in our case) just like GSSAPI does ;-)
So there is no integrity or privacy protection with this patch, correct? Do you have a URL which documents gssapi IMAP?
(In reply to comment #3) > Great, thx, Christopher. I'll wait for your patch before proceeding since there > might be conflicts. I'll attach the standalone gssapi.h, though perhaps you have > your own? I don't have my own gssapi.h. I had considered it but didn't know the ramifications. But, if you have reason to believe there will be less problems using a custom version then jumping through hoops to find the system version, then I'm game. We can probably do the same sort of thing for the SSPI. SSPI/Kerberos Interoperability with GSSAPI http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secauthn/security/sspi_kerberos_interoperability_with_gssapi.asp Could we just make nsIAuthModule more general and create a wrap and unwrap function? Would that suffice so that we don't need all of the sasl code in the kerberos module?
>So there is no integrity or privacy protection with this patch, correct? I believe that's correct. Simon could say for sure, and why that is, I assume. > Do you have a URL which documents gssapi IMAP? I don't - I googled for a bit and couldn't find anything. I think having our own gssapi.h is the way to go. I've got one that works on Windows, and I believe the guy who sent it to me used it on Linux. I'll attach it, and finding out what kind of license I can slap on it.
Attached file standalone gssapi.h (obsolete) —
If anyone wants to try this file on linux/mac, that would be useful. It builds on windows when I change nsNegotiateAuthGSSAPI.h to just include this gssapi.h
>Could we just make nsIAuthModule more general and create a wrap and unwrap >function? Would that suffice so that we don't need all of the sasl code in the >kerberos module? I think we could just have different negotiateAuth class for the gssapi/sasl stuff, or use a sub-class. But I think the auth module implementation should be doing the wrap/unwrap stuff itself, and hide that detail from the consumers. But I may not understand what you're suggesting.
Replying to lots of comments here. Bear with me. comment#10: There is no support for integrity or privacy protection in this patch. To do this, you'd need to implement SASL security layers. This would require additional interface-fu, as you need to be able to call gss_unwrap() for all incoming packets, and gss_wrap with all outgoing ones. Supporting security layers in the future would be a Good Thing, IMHO, so maybe that should be considered when deciding on the way to integrate GSSAPI. comment#10: GSSAPI IMAP is defined by a number of RFCs. RFC2222 defines SASL, and the GSSAPI SASL mechanism. Its use within IMAP is defined in the IMAP RFC. I'd suggest also reading the rfc2222bis I-D, and the revised GSSAPI SASL mechanism I-D, which clarify a number of implementation points. See http://www.faqs.org/rfcs/rfc2222.html , http://www.ietf.org/internet-drafts/draft-ietf-sasl-rfc2222bis-11.txt and http://www.ietf.org/internet-drafts/draft-ietf-sasl-gssapi-02.txt comment#11: The GSSAPI C bindings are defined by RFC2744. Appendix A of this document provides a definitive gssapi.h header file, which will be correct for all conformant GSSAPI implementations. comment#11: It did occur to me whether it might be easier just to create a 'GSSAPI' module which exposes NextToken(), Wrap(), and Unwrap() functionality. Doing this would make it easier to add security layers in the future. comment#13: The header file you have attached is from the Globus GSSAPI implementation. It contains references to non-standard functions and flags. I don't think that you should use it in its current form.
Why are you writing your own sasl implementation rather than just linking in either the system sasl libs, or trying to do something with mozilla's ldap sasl libs?
mailnews already has its own SASL implementation. The CRAM-MD5, NTLM, MSN, PLAIN and LOGIN methods implemented within AuthLogin() are all SASL mechanisms. So the code doesn't create a new implementation, rather just extend an existing one. The additional code in the patch David attached for NegotiateAuth is the sum total of what is required to do SASL/GSSAPI - I think that adding a dependency on Cyrus SASL, plus having to implement for Windows anyway, would be signifcantly more work and more code. IMHO Cyrus SASL has made people think that SASL implementations are heavyweight (and even to think that there's such a thing as a 'SASL implementation' - you don't implement SASL, you implement the mechanisms individually - SASL is just a framework for defining how you define a mechanism) They're not - its the glue that the Cyrus libraries have to make them all things to all people that adds to the code bulk.
OK, I've removed the non-standard stuff that I could find from this gssapi.h - it should be pretty close to what's in the rfc now with <platform-specific> stuff filled in.
Attachment #190794 - Attachment is obsolete: true
Attached file add license
Does this look OK? I put our license notice in, and put the author of rfc 2744 as the original author. Since the RFC says clients *should* include this header file, I doubt they care much about it :-)
Attachment #190836 - Attachment is obsolete: true
Attachment #190882 - Flags: review?(cneberg)
(In reply to comment #17) > mailnews already has its own SASL implementation. Ok thanks for clearing that up. I think nsIAuthModule interface should have a Wrap and Unwrap function. I can add these functions to both SSPI and GSSAPI Kerberos. Then you should make a new nsIAuthModule for gss-sasl (or whatever you want to call it). It will create a component of either gss or sspi and call their wrap and unwrap functions as needed. Then you won't have to duplicate your sasl code twice, you can ignore the differences between the kerberos implementations, and we will have the start of an implementation to do security layers at a later point. You can put all of your logic under your aut module's GetNextToken and leave the Wrap and Unwrap of your module empty for the time being. How does that sound?
(In reply to comment #20) That sounds good. The only other requirement here would be that GetNextToken() has a set of return codes that differentiate between partial (GSS_S_CONTINUE_NEEDED) and complete success. The gss-sasl implementation would need this to tell when to start its bit of the handshake. Is there a pref to determine whether to do gss or sspi?
> That sounds good. The only other requirement here would be that GetNextToken() > has a set of return codes that differentiate between partial > (GSS_S_CONTINUE_NEEDED) and complete success. The gss-sasl implementation would > need this to tell when to start its bit of the handshake. Fine. I will also probably need some flags which specify the gss-mech to use. (You probably really want kerberos not SPNEGO even it is available) > > Is there a pref to determine whether to do gss or sspi? Your module would probably have to determine which one it wanted to use since gssapi and sspi will really be two different nsIAuthModule implementations. I was going to create a pref in bug 280792 in the http layer to let the user decide. You could base your decision on the exact same pref or a different one depending on what your needs are.
I was hoping to be able to get this into 1.5, which is probably going to stop accepting new features in a week or so - does anyone think that's undoable/crazy? Does anyone need anything from me? I'm ready and willing to help with any of this.
(In reply to comment #23) > I was hoping to be able to get this into 1.5, which is probably going to stop > accepting new features in a week or so - does anyone think that's undoable/crazy? I'll try to do as much of the kerberos changes as possible this weekend. There were a few problem areas for negotiateauth and HTTP authentication initially and to save time I'd like to document them here so you can consider them and fix them in parallel if you forsee the same problems ocurring in mail. Can mailnews handling the following scenarios adequately? Kerberos is different than every other auth protocol because it normally doesn't make sense to retry kerberos if auth fails for some reason. It either succeeds or fails on the first try then you need to fail over to another authentication type transparently. senario's 1. The gss auth module can't be loaded. 2. The module can be loaded but getNextToken fails because the user has no credentials. 3. getNextToken succeeds and sends a token but that token is rejected by the server. 4. getNextToken succeeds and sends a token but that token is rejected by the server, then multi-trip auth protocol like NTLM is called next. Between the first and second trip for NTLM, you want it to remember that mail is doing NTLM and not go back and try kerberos again between the attempts and get into an infinite loop.
we fail over on all the secure auth mechanisms because some servers claim to support a particular mechanism but fail. Simon is making sure we propagate the various failures in gssapi auth to the code that does the failover.
Close this bug? Either -> Resolved Fixed or maybe mark it as a dup of 280792?
Status: NEW → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Keywords: fixed1.8
Comment on attachment 190882 [details] add license cancelling obsolete request.
Attachment #190882 - Flags: review?(cneberg)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: