Open Bug 524698 Opened 15 years ago Updated 2 years ago

GSSAPI/Kerberos-Auth should log on and get a Ticket-Granting-Ticket, if client doesn't have a ticket yet

Categories

(MailNews Core :: Security, defect)

All
Linux
defect

Tracking

(Not tracked)

ASSIGNED

People

(Reporter: BenB, Assigned: BenB)

References

Details

Attachments

(2 files, 4 obsolete files)

Reproduction:
1. Configure an IMAP server to offer GSSAPI auth, and no plaintext auth.
2. Configure Thunderbird to use this server.
   Set "secure auth" checked and unchecked, i.e. test both.
3. kdestroy, to clear all your Kerberos tickets (=authorization tokens).
4. Click on the Inbox of that server.

Actual result:
If "secure auth" is off:
Error: "You cannot log in to <server> because the server doesn't allow plaintext authentication without STARTTLS or SSL/TLS. Try enabling connection security or secure authentication in the account settings."
If "secure auth" is on:
Error: "You cannot log in to <server> because you have enabled secure authentication and this server does not support it.
To log in, turn off secure authentication for this account."
Repeat ;-)

Other situations:
If you do "kinit" and got a TGT manually and repeat the steps, you can log in without password and without error.

Expected result:
Thunderbird makes a platform-specific dialog come up that asks for the password and requests the TGT (Ticket Granting Ticket), and waits for that to complete (or fail), and then requests a ticket for the imap server (as it currently does when the TGT already exists).

At the absolute minimum, give a dialog that asks the user to log in to Kerberos (get the TGT).
Note: there are servers which advertise GSSAPI in CAPABILITY, but have not set it up properly.
Summary: GSSAPI/Kerberos-auth fails with strange error, if client doesn't have a ticket yet → GSSAPI/Kerberos-auth fails with wrong error, if client doesn't have a ticket yet
On (some) Linux, you can trigger the Kerberos login via DBus:
<http://honk.sigxcpu.org/con/krb5_auth_dialog__dbus_interface.html>
Ben could you provide accounts for either bienvenu or bwinton ?
I only have a private server, but maybe I could provide a public server, on request, if really needed.
I could also work with gozer to help him set up a test server in the MoMo zoo.
caillon, you wrote krb5-auth-dialog, according to the man page.
Any input?
Depends on: 524733
I think this works for the mac.

On windows, we have to deal with sspi and kerberos, which might make it tricky.
Talked with bienvenu on IRC. Apparently it used to work on the Mac, but suboptimal, and was disabled in bug 240643.


The code that implements GSSAPI in Mozilla is mozilla/extensions/auth/nsAuthGSSAPI.cpp - at least for Linux. It's called in mailnews/base/util/nsMsgProtocol.cpp.

http://mxr.mozilla.org/comm-central/source/mozilla/extensions/auth/nsAuthGSSAPI.cpp
http://mxr.mozilla.org/comm-central/source/mailnews/base/util/nsMsgProtocol.cpp#835

On Windows, we use SSPI, Microsofts own API to GSSAPI, NTLM etc., by default, says bienvenu. That's also implemented in extensions/auth/.
My main problem is
1) how/where do I invoke UI for asking the password
2) may DoGSSAPIStep1 block for the UI (probably not),
   or do I need another step?
Worse, the implementation seems to be separate for every protocol (IMAP, POP3, IMAP).
For IMAP, I *may* be lucky, because the CRAM-MD5 code is in the same function and gets a password passed in.
the DoGSSAPIStep1/2 implementations are shared. The protocols are all different, however, (though IMAP shares a lot of code with IMAP :-)) so there's no way they could share the actual implementation (e.g., POP3 uses a state machine and runs on the UI thread, IMAP runs each connection on its own thread).
> POP3 uses a state machine and runs on the UI thread

Ah, yes, that's why it looks so different.

I had a long and useful conversation with sxw on IRC. Results (please disagree, if anything is factually wrong):

- nsAuthGSSAPI stuff (DoGSSAPIStep1/2) may block. It already blocks on network, and it would be OK to block on the password prompt, too.
- sxw thinks that applications by principle should not pop up password prompts for Kerberos. It should be an OS dialog. I thought it would be nicer to have a Mozilla dialog, but it seems it's actually *better* to use krb5-auth-dialog (on Linux).
- Using krb5-auth-dialog is fairly easy: you just call a DBus interface (see comment 2), and it pops up the dialog. The DBus function does not return (i.e. blocks) until the user either entered the correct password and aquired a valid TGT, or he explicitly canceled (in which case the DBus function returns an error). Even a wrong password does not cause the function to return. If there already is a valid TGT, no password prompt comes up, and the function returns immediately with success. In other words, the API is *perfect* for us (congrats caillon and Guido): It's blocking until we got a TGT, or returns an error on Cancel.
- Mozilla already uses DBus in a few places, including configure test, so the dependency is not a problem. We can simply call the DBus functions from C++.
A few possible gotchas:
- We may get several auth requests at the same time, or in a row. We can take care that with a proper threadsafe lock, on which we block.
- HTTP servers may advertise GSSAPI although it's not supported. But that's not a problem, because Kerberos / NTLM ("Negotiate Auth" in our code) is only used, if the hidden pref (no UI) "network.negotiate-auth.trusted-uris" is configured specifically for that server.
- Mail (IMAP, POP, SMTP) servers may advertise GSSAPI although it's not supported. We can solve that by changing the current "Secure auth" pref in a 3 state enum: "plaintext auth", "encrypted password AUTH" (MD5 et al), and "secure ticket auth (Kerberos, NTLM)". It would be exposed as dropdown in the Account Manager, and autodetected in the new Account Creation Wizard (try Kerberos, and if it works, enable it, if it fails, do what we do now: fall back to MD5 password, then fall back to plaintext password, and hard configure the best method that worked). I always thought that makes sense and the "secure auth" lumps too much together and is incomprehensibly vague.
(In reply to comment #10)
> > POP3 uses a state machine and runs on the UI thread
...
> - nsAuthGSSAPI stuff (DoGSSAPIStep1/2) may block. It already blocks on
> network, and it would be OK to block on the password prompt, too.

hm, how do the above two statements fit together?
> - We may get several auth requests at the same time, or in a row. We can take
> care that with a proper threadsafe lock, on which we block.

We take care of that "several in a row" (e.g. more requests come in after the user already canceled the Kerberos prompt) by a short-lived flag, sxw and me think it should be in necko, probably in the load group or http implementation.
(In reply to comment #11)
> (In reply to comment #10)
> > > POP3 uses a state machine and runs on the UI thread
> ...
> > - nsAuthGSSAPI stuff (DoGSSAPIStep1/2) may block. It already blocks on
> > network, and it would be OK to block on the password prompt, too.
> 
> hm, how do the above two statements fit together?

DoGSSAPIStep1/2 don't block - they calculate some data that the protocol code then sends to the server, and the protocol code doesn't block the ui when it reads or writes to the network.  However, it's OK for the UI thread to put up a password prompt...
> DoGSSAPIStep1/2 don't block

From what sxw, and what I read in the code, they do: DoGSSAPIStep1() calls authModule->GetNextToken(), which calls gss_init_sec_context(). The latter goes to the Kerberos server.
<http://docsun.cites.uiuc.edu/sun_docs/C/solaris_9/SUNWdev/GSSAPIPG/p12.html>

(That's natural: Kerberos needs to go to the Kerberos server to get a ticket for the service each time it wants to connect to a new server.
When you authenticate to the Kerberos server, when entering your password, the Kerberos server gives you an "Ticket Granting Ticket" (TGT). When you want to authenticate to a service like IMAP, you don't send that TGT, but you ask the Kerberos server, using the TGT, for a ticket specifically for that IMAP server, and the Kerberos server gives you a ticket that says "ben@example.com may connect to IMAP at imap.example.com". You hand that ticket to the imap.example.com server, which can verify it and grants you access.
So, you need to go to the Kerberos server whenever you connect to the IMAP server, so the authentication (DoGSSAPIStep1()) inherently requires a network connection.)

So, I take it that we currently block the UI thread in POP on network connections, and we were not aware of that?

> However, it's OK for the UI thread to put up a password prompt...

Yes. Note, however, that the UI would be an OS dialog in a different process.
I think we don't want the user (or app) to do anything during that time anyways, but it's still not kosher.
>So, I take it that we currently block the UI thread in POP on network
>connections, and we were not aware of that?
Sounds like it - I don't know how common pop3 access w/ Kerberos is. IMAP calls DoGSSAPIStep1/2 from the imap thread, so it doesn't block the UI thread.
> I don't know how common pop3 access w/ Kerberos is

I think we do that whenever the server advertises GSSAPI (which I think is far more often than Kerberos actually set up, esp. at badly administered servers, maybe not so much at ISPs) and "secure auth" is enabled.
Either way, this seems like a bug, so I filed bug 524963.

Do you think it's acceptable to block the UI thread during POP authentication while we put up the OS password dialog (different process)?
That would be fixed when bug 524963 is fixed.
(In reply to comment #16)
> > I don't know how common pop3 access w/ Kerberos is
> 
> I think we do that whenever the server advertises GSSAPI (which I think is far
> more often than Kerberos actually set up, esp. at badly administered servers,
> maybe not so much at ISPs) and "secure auth" is enabled.

I would think Kerberos would need to be installed and configured on the client machine as well before we'd do any network activity, which would cut out the vast majority of users.
Depends on: 525238
TODO:
- Make mail "secure auth" a 3-state pref - I just filed bug 252238 for that.
- Add threading lock
- Add necko flag in load group or http to remember avoid
  several TGT password prompts in a row.
- Other platforms than Linux GNOME :)
Dupe of bug 339050
Also Bug 370178, Ben you seems been in hurry last time when filled these bugs ;)
OK, this bug was only marginally about the bad error message anyways, so I'll change this to focus on getting a TGT, and leave the old bug for the error message, and make this depend on the old one.
Depends on: 339050
Summary: GSSAPI/Kerberos-auth fails with wrong error, if client doesn't have a ticket yet → GSSAPI/Kerberos-Auth should log on and get a Ticket-Granting-Ticket, if client doesn't have a ticket yet
This should take care about ticket if it expired too.
Yes, expired ticket is same as no ticket :)
(In reply to comment #23)
> This should take care about ticket if it expired too.

This is handled by the underlying helper to acquire the password. It shouldn't distinguish between invalid and expired. krb5-auth-dialog does it this way. Thunderbird shouldn't care about the difference either.
Attached patch Fix, v1 (obsolete) — Splinter Review
This creates an XPCOM component API with contract ID "@mozilla.org/network/auth-module/gssapi-get-ticket" and lets the GSSAPI code call it when the ticket failed. It's made so that there can be competing implementations of it.

It contains one implementation which looks at the pref "auth.gssapi.ticketgetter.command" and runs that application/script (if it exists), with the service name ("imap@serverhostname") as first parameter. This allows admins flexibility in adapting to local circumstances.

I intend to also write a second implementation using DBUS to call org.gnome.KrbAuthDialog .

But I don't know yet how to ship both implementations and let one of them have (configurable) precedence.
It would be nice to not call this depending on the mail authMethod preference != GSSAPI introduced in bug 525238. But I don't know how to pass that information on, given that this is core code and mail can't pass it additional params.

As-is, we would call the new function when we migrate/use useSecAuth ("secure auth") (from 3.0 to authMethod = "any secure" in 3.1), on servers which advertize GSSAPI, but don't support it. (If the server doesn't advertize GSSAPI, we won't try it, even if "any auth"). But even if the new function is called, but the pref is empty or the script doesn't exist, nothing happens. Similarly, if we make a DBUS call to a non-installed component, nothing happens. So, shouldn't be so bad, but would be nice to do better.
Status: NEW → ASSIGNED
Attached patch Fix, v3 (obsolete) — Splinter Review
Includes implementation for GNOME KrbDialog via DBUS, via a separate XPCOM component.

TODO:
- Switch between implementations
  (currently need to set a #define and |make| on mozilla/ top-level)
- Possibly wait for password before returning function
  (implemented as option in GetTicket(), but not sure if good idea or how)
- use authMethod mail pref (comment 27)
Attachment #426742 - Attachment is obsolete: true
> Switch between implementations

For nsIFilePicker (a similar situation), we basically
1) have several implementations for the same contractID, some of them mututally exclusive (per platform), some not (XUL filepicker)
2) we have a pref to switch
3) we have a custom factory function for that contractid, to consult the pref
<http://mxr.mozilla.org/comm-central/source/mozilla/widget/src/gtk2/nsWidgetFactory.cpp#153>
Sounds like that might work here, too :)
> Switch between implementations

Solved that by:
1) Shipping with the "script" implementation by default
2) Creating the GNOME dialog hookup implementation as extension,
   which registers under the same contract ID.
Extensions override internal components with the same contract ID,
so if you have the GNOME dialog extension installed, that one will be used,
otherwise the default "script" implementation will be used.
> wait for password before returning function

Done. I now throw up the password dialog / script only when we failed to get a proper ticket (because of lacking a valid TGT).
I start the script in "auth.gssapi.login.command" (I changed the pref name),
or the GNOME implementation makes a DBUS call.
If the pref "auth.gssapi.login.wait" is true (which is the default), we wait until the dialog or script finished, i.e. until the user either entered a password or canceled the OS password dialog. Then we try to get the ticket again. (If that fails, we don't show the password dialog again.) Only then does the function GetNextToken() return.

So, from a code perspective, you call GetNextToken(), and unless the user didn't want to enter the password, you have a valid ticket when it returns.
From a user perspective, they click on the Inbox, and they are either directly logged in, if they already have a valid TGT, or they get an OS password dialog, they enter the password and press OK, and Thunderbird proceeds and logs them in and shows the mails.

This is good usability, but has a technical problem: The POP3 and SMTP implementations are on the UI thread, which means the whole Thunderbird UI will freeze while the OS password dialog is up. IMAP is fine, because it's running in a thread. (And the vast majority of Kerberos users will use IMAP, so I hope this is not a big problem in practice.) Note that this is not a new problem, just aggrevated: POP3 already blocks the UI on the GSSAPI network calls. I filed bug 546027 about that.
So, if that bothers somebody, they can set the pref "auth.gssapi.login.wait" to false, that's why I added it. I think the default should be true because of the better usability.
Attached patch Fix, v4 (obsolete) — Splinter Review
Changes:
- GNOME implementation moved to an extension (not in this patch)
- Wait for password and retry to get a ticket before failing
TODO:
- use authMethod mail pref (comment 27)
Attachment #426777 - Attachment is obsolete: true
Independent extension, but needs Fix v4 in core.
Comment on attachment 426842 [details] [diff] [review]
Fix, v4

requesting review
Attachment #426842 - Flags: review?(bzbarsky)
The idea here is good, but I think the implementation is a little flawed as it stands ...

Firstly, nsAuthGSSAPI is shared with firefox, which uses it to implement NegotiateAuth. With Firefox's use, a different instance of nsAuthGSSAPI is created for each connection - which may result in many, many, of these running simultaneously. I'm not convinced that the protection against multiple ticket prompting is sufficient for that case.

Secondly, you're prompting for a TGT whenever gss_init_sec_context fails. There are many reasons this call may fail, and it isn't appropriate to prompt for tickets in all of them. You should examine the error code, and only prompt for credentials if you are told that credentials are either missing, or expired. Ideally, you should also ensure that the missing credentials are actually the local ones by attempting to open the local credentials cache with gss_acquire_cred()

Thirdly, you can't restart a context establishment mid way through - you should only do the ticket check if the first call to gss_init_sec_context fails. If you then get tickets, you must restart the context establishment. As the code currently stands, you may attempt to switch tokens midway through context creation, which is an error.

Fourthly, the comments above 'GetNextToken' are incorrect. This function doesn't get a ticket, nor is it guaranteed to make network calls. Nor is it, in this class, restricted to purely performing Kerberos - Firefox may use this to call out to SPNEGO libraries on some platforms.

Finally, calling out to an external script seems very clunky and fragile. Is there a reason we're adding this, rather than just supporting the DBus interface?
> 1. many, many, of these running simultaneously

From earlier comments of yours, I remember you being familiar with this situation. Do you have a concrete suggestion how to solve this?

> 2. You should examine the error code

Ah, if the function provides that, all the better, I'll try to use it.

> 3. you can't restart a context establishment mid way

I didn't understand this at all. I simply call the same function again with the same parameters. Presumably, TB would do the same if it was to retry the connection.
Or do you mean I should call |Reset()|?

> 4. the comments above 'GetNextToken' are incorrect. This function
> doesn't get a ticket, nor is it guaranteed to make network calls.

It *may* make network calls, which is the important thing for callers. I'll add the "may". (bienvenu was not aware that this makes network calls.)

As far as I understand, this function does get a ticket for the service. Not a TGT, but a ticket for e.g. imap@servername, which is then presented to the imap server.

> Finally, calling out to an external script seems very clunky and fragile. Is
> there a reason we're adding this, rather than just supporting the DBus
> interface?

I do support the DBus interface, with the extension. But that API only works with that particular GNOME applet, it calls out to service "org.gnome.KrbAuthDialog", object "/org/gnome/KrbAuthDialog". It will only work if that applet is running.
KDE has a "kredentials" (sic) which I think uses DCOP.
Mac and Windows will work differently, too.
That's why I created pluggable components to offer a dialog and get a TGT.

However, calling apps or scripts will work on almost any platform. More importantly, admins for large installations can quickly write their own solutions, either to implement any of the above themselves, or to adjust them to their needs.

It's "clunky and fragile" at all. In fact, the author of krb5-auth-dialog published 2 different ways to call that dialog from scripts:
<http://honk.sigxcpu.org/con/krb5_auth_dialog__dbus_interface.html>
<http://honk.sigxcpu.org/con/offlineimap_and_krb5_auth_dialog.html>
The API of the dialog, and these scripts, are designed to return only when the user either acquired a TGT or explicitly canceled. (They don't even return when the user entered the wrong password and is allowed to try again.) So, his would work nicely with scripts. I tried it myself, with a simple kdialog --msgbox, too, and it works well for me.

I honestly don't know what admins will prefer. Both have advantages.
Attachment #426842 - Flags: review?(bzbarsky)
(In reply to comment #35)
> Secondly, you're prompting for a TGT whenever gss_init_sec_context fails. There
> are many reasons this call may fail, and it isn't appropriate to prompt for
> tickets in all of them. You should examine the error code, and only prompt for
> credentials if you are told that credentials are either missing, or expired.
> Ideally, you should also ensure that the missing credentials are actually the
> local ones by attempting to open the local credentials cache with
> gss_acquire_cred()
The idea here is to have most of this handled via the DBus API. IMHO Thunderbird/Firefox should not have to care about all the GSSAPI/Kerberos stuff like opening the local credentials cache since this can become very cumbersome with different implementations. Looking at the error code and deciding if we need to get credentials should be enough. If the DBus API is lacking functionality, just let me know.
(In reply to comment #36)
> > Finally, calling out to an external script seems very clunky and fragile. Is
> > there a reason we're adding this, rather than just supporting the DBus
> > interface?
> 
> I do support the DBus interface, with the extension. But that API only works
> with that particular GNOME applet, it calls out to service
> "org.gnome.KrbAuthDialog", object "/org/gnome/KrbAuthDialog". It will only work
> if that applet is running.
The applet doesn't need to run. DBus will fire it up if it sees the call and the applet isn't running.

> KDE has a "kredentials" (sic) which I think uses DCOP.
I'm not sure there's a DCOP API in Kredentials that allows programs to request TGT acquisition. The grand plan is to make the org.gnome.KrbAuthDialog API cross desktop in the long run - that said it can of course be already used on KDE without problems. So I think we don't need to have the Ticket acquisition code pluggable, it only needs to be platform dependant so Windows and MacOS can have different implementations.

> Mac and Windows will work differently, too.
> That's why I created pluggable components to offer a dialog and get a TGT.
(In reply to comment #37)
> The idea here is to have most of this handled via the DBus API.

The problem is that the no credentials error can mean either "client has no credentials" or "server principal doesn't exist in KDC". In the first case, you probably want to prompt the client to renew their TGT. In the second, you don't want to do anything. Does the application receiving the DBus calls have enough intelligence to work out which is which? How does it cope with recent Heimdal where a user can have more than one TGT in their credential cache?

> IMHO  Thunderbird/Firefox should not have to care about all the GSSAPI/Kerberos stuff
> like opening the local credentials cache since this can become very cumbersome
> with different implementations. 

It's actually pretty trivial - you can do it all through the GSSAPI. Get a handle for the credentials by calling gss_acquire_cred, and request initiator credentials. Then use gss_inquire_cred to find out things like expiry time. This is guaranteed to work with any GSSAPI library.

> Looking at the error code and deciding if we need to get credentials should be enough.

As I've said, my experience is that the error code doesn't definitively tell you that you need credentials. It provides a pretty good approximation, though - depending on the intelligence of the thing at the other end of the DBus, checking for particular errors might be enough.
(In reply to comment #36)
> > 1. many, many, of these running simultaneously
> 
> From earlier comments of yours, I remember you being familiar with this
> situation. Do you have a concrete suggestion how to solve this?

I think you need to have a singleton class which handles communication with the TGT getting service, and remembers when there is a request in progress (or even, when a request has been recently made)> That class can then throttle the frequency with which we request new TGTs (it's important that we also honour the user's decision to cancel out, and not get a TGT)
 
> I didn't understand this at all. I simply call the same function again with the
> same parameters. Presumably, TB would do the same if it was to retry the
> connection.

TB creates a new instance of this class for each connection. You need to call Reset() if you're starting again having changed TGT.
 
> > 4. the comments above 'GetNextToken' are incorrect. This function
> > doesn't get a ticket, nor is it guaranteed to make network calls.
> 
> It *may* make network calls, which is the important thing for callers. I'll add
> the "may". (bienvenu was not aware that this makes network calls.)

GetNextToken isn't a Kerberos function, and even when it is, it doesn't necessarily always result in getting tickets. All you can say for sure is that it carries out a step in establishing a GSSAPI context.
This class is already used with two different GSSAPI mechanisms (SPENGO, wrapping  NTLM, and Kerberos), and it's possible that it may be used with many more.

> As far as I understand, this function does get a ticket for the service. Not a
> TGT, but a ticket for e.g. imap@servername, which is then presented to the imap
> server.

It may, as part of the context establishment, get a ticket. But that's all at least one abstraction layer away from you.
 
> Mac and Windows will work differently, too.
Mac and Windows (both SSPI and KfW) have their own mechanisms for prompting the user when a TGT has expired. We shouldn't be doing anything on either of those platforms - if the system mechanism isn't asking the user, then its been disabled by choice.

> However, calling apps or scripts will work on almost any platform. More
> importantly, admins for large installations can quickly write their own
> solutions, either to implement any of the above themselves, or to adjust them
> to their needs.

It's pretty fundamental to the security of Kerberos that users _only_ give their TGT to trusted applications. I'd strongly prefer that we not make it easy for administrators to shoot themselves in the foot by having a pluggable API for scripts for this.

One further point. The call out to get a TGT should only occur if we know that we're using Kerberos to talk to the server - you should check the mechanism that is being used, and only do the TGT call out if that mech is Kerberos. This is of theoretical importance for Thunderbird, but is critical for Firefox.
(In reply to comment #40)
> (In reply to comment #36)
> > Mac and Windows will work differently, too.
> Mac and Windows (both SSPI and KfW) have their own mechanisms for prompting the
> user when a TGT has expired. We shouldn't be doing anything on either of those
> platforms - if the system mechanism isn't asking the user, then its been
> disabled by choice.

There are two different situations:
* The credentials expire. Krb5-auth-dialog already handles this (automatic renewal and password/SmartcardPin prompting)
* The user doesn't have a valid ticket after logon like in mobile solutions. Then we'd have to prompt for the password/SmartcardPin the first time we need a Ticket (e.g. when connecting to the imap server).

I wonder how MacOS X or Windows handels the last case (AFAIK Windows simply falls back to NTLM). Do you have any pointers on how this is implemented? Maybe we can do the same then.
> This class is already used with two different GSSAPI mechanisms

The IDL, yes. This class, no. This class (nsAuthGSSAPI) is concrete and only about the GSSAPI lib, not SPENGO.

> But that's all at least one abstraction layer away from you.

That's what caused bug 546027 and makes people not understand things. Despite abstraction, developers using the API need to know what actually happens, without being a GSSAPI expert. That's what Javadoc is for.

> It's pretty fundamental to the security of Kerberos that users _only_ give
> their TGT to trusted applications.

The script doesn't give out TGTs to applications, it only invokes the OS password dialog. If the user already has a TGT - which is true under normal conditions -, a bad app wouldn't need the script, it could simply get a ticket from the gssapi lib.

> The call out to get a TGT should only occur if we know that
> we're using Kerberos to talk to the server

Comment 27.

> critical for Firefox.

I assumed that Firefox only invokes this when it knows the server wants Kerberos. I lack the knowledge how HTTP auth with Kerberos works in practice, and the solution depends on that, and therefore cannot provide a solution.
Correction: nsAuthGSSAPI does use SPNEGO. (Still, the original comments hold: This function may cause and block for network calls, which developers who call this must be aware of and cater to, bug 546027).
> we don't need to have the Ticket acquisition
> code pluggable, it only needs to be platform dependant

FWIW, even if there was only one implementation per platform, I'd still make it an XPCOM IDL API with one contract ID and several implementations, like I did now, given how much the platforms differ.
Attached patch Fix, v5 (obsolete) — Splinter Review
Changes:
- Added Reset()
- Checked for error code
  (unfortunately, I had to include GSS_S_FAILURE, because that's what my
  OS gssapi lib sends for no TGT, so this error code check is pretty useless,
  and may cause it to not work in case other implementations send yet
  other error codes in this case.)
- Fixed comment

I answered the other comments above.

TODO:
- Protect against multiple simultaneous calls
  (per Simon, using a semaphore)
- Find out whether Firefox calls this for non-Kerberos servers
  and what to do. (Help needed)
- Thunderbird: send authMethod (comment 27)
Attachment #426842 - Attachment is obsolete: true
Simon, do you have examples (servers) for the following?

1. Multiple simultaneous calls:
> NegotiateAuth. With Firefox's use, a different instance of nsAuthGSSAPI is
> created for each connection - which may result in many, many, of these running
> simultaneously.

2. Firefox asking for Kerberos, when it's not actually a Kerberos server:
> The call out to get a TGT should only occur if we know that
> we're using Kerberos to talk to the server - you should check the mechanism
> that is being used, and only do the TGT call out if that mech is Kerberos. This
> is of theoretical importance for Thunderbird, but is critical for Firefox.
Attached patch Fix v6Splinter Review
Changes:
- Added global lock to protect GetTGT()
  (I tried using mozilla::Monitor in xpcom/glue/Monitor.h, but there's
  no IsLocked(), which I need for the block == false case.)

Works for me in normal case, but can't test the "multiple instances" case, lacking a test case (last comment).
Attachment #426928 - Attachment is obsolete: true
Thanks to bent for his help on this mutex stuff!
(In reply to comment #39)
> (In reply to comment #37)
> > The idea here is to have most of this handled via the DBus API.
> 
> The problem is that the no credentials error can mean either "client has no
> credentials" or "server principal doesn't exist in KDC". In the first case, you
> probably want to prompt the client to renew their TGT. In the second, you don't
> want to do anything. Does the application receiving the DBus calls have enough
> intelligence to work out which is which? 
No and it probably shouldn't. The application has all the GSS Error codes right at it's hands.

> How does it cope with recent Heimdal
> where a user can have more than one TGT in their credential cache?
You can pass the requested principal on via DBus. At the moment it will fail if it dosn't match the principal in the cache. If the underlying Kerberos implementation supports more then one TGT in the cache we can add them to the cahche, although that's not implemented yet.

> > IMHO  Thunderbird/Firefox should not have to care about all the GSSAPI/Kerberos stuff
> > like opening the local credentials cache since this can become very cumbersome
> > with different implementations. 
> 
> It's actually pretty trivial - you can do it all through the GSSAPI. Get a
> handle for the credentials by calling gss_acquire_cred, and request initiator
> credentials. Then use gss_inquire_cred to find out things like expiry time.
> This is guaranteed to work with any GSSAPI library.
This will get you a handle to existing credentials. So we could check if the credentials are still "valid" and if not call out via e.g. DBus so we stay of out of all the trouble that comes with ticket acquisition like PKINIt. Makes sense.
See Also: → 546027

can't test the "multiple instances" case, lacking a test case (last comment).

Is this the only remaining sticking point?

Flags: needinfo?(ben.bucksch)

Sorry, this is 12 years ago, I really cannot remember anything, other than what is written here. Some contributor asked me to test a specific case in a particularly complex (and probably rare) setup, and I was just not able to test that, because I didn't have the server setup. That's what I'm understanding from the comments.

From what I can see, there was a working patch, but it was never reviewed. From what I can see, that was the problem why this was stuck.

Flags: needinfo?(ben.bucksch)
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: