Hello, I'd like to slightly improve the negotiate authentication mechanism.
The motivation is that, by using the Negotiate (and probably also NTLM) auth mechanism, it should be possible to support SSO-only authentication, in the sense that either the client authenticates transparently (without prompting the user), or the mechanism is dropped entirely and the user is either not authenticated or authenticated in a different way. This is useful for example if you want to transparently authenticate clients in a windows domain and reject others, or maybe either authenticate clients via kerberos but, if the client doesn't have a valid kerberos ticket, then switch to a different mechanism (such as "basic" against an ldap server). The way this works is that the server first returns a 407 page with e.g. 2 headers: Authenticate: Negotiate and Authenticate: Basic; then the browser tries with its kerberos ticket or current user's ntlm credentials (without user interaction); if those are accepted then fine, otherwise the server returns a new 407 page again with just the Authenticate: Basic header and not the Negotiate one (this behavior is supported e.g. in the java spnego sourceforge project and the apache spnego module). Unfortunately this is not possible with squid because, when Negotiate fails, squid returns a new 407 page that includes the "Authenticate: Negotiate" header again. Note that when using the squid_kerb_auth helper, this causes the browser (in the case that the client has no valid kerberos ticket) to repeatedly prompt the user for NTLM credentials that will never get accepted by the helper anyway (and never switches to Basic). So the idea is to extend the negotiate helper protocol so that the helper can specify that its auth mechanism should no longer be offered to the client (this might be useful for other mechanisms too). This way it would be up to the helper to decide if its scheme should be reiterated or not. I have written a proof-of-concept patch that keeps the protocol as is but, for the h->s messages (which are of the form "XX blablabla"), it also recognizes the variant "XX.blablabla" (that is with a dot instead of a blank after the 2-letters message ID) with the meaning: "final, do not offer this mechanism again". This can make sense both for BH/NA (auth failed) messages and for AF messages (in case that auth was successful but the user is not authorized to get the requested page). It is probably useless in TT messages. My main doubt is where to keep the information about "disabled" schemes. In my current test I keep a list of "still active" auth schemes in the HttpRequest object. However the problem with this is that the httprequest object is (seems to be) freed as soon as the connection is closed. Therefore this works only for the first auth reiteration, that is, this is what can happen: - client requests a page - squid requires auth and proposes e.g. negotiate and basic - client tries negotiate with invalid credentials (e.g. with ntlm instead of kerberos) - squid doesn't accept the credentials, eventually marks negotiate as disabled (if the helper says so) and proposes only basic, then closes the connection and drops the httprequest object - client tries basic with invalid credentials - squid rejects again but at this point doesn't "remember" that negotiate is disabled, so proposes negotiate and basic again While this works anyway (it just causes the browser to retry with SSO another time, before prompting the user again for other Basic credentials), it doesn't seem right. One possible solution could be to not force a connection-close after a failed authentication (it shouldn't be necessary, should it?). But maybe there are also other objects that are more suitable to keep this information and that persists at least until authentication is fully completed? I'd be happy to get your advice on this point and the whole idea. Thanks Livio
