Re: "negotiate" auth with fallback to other schemes

2010-03-06 Thread Markus Moeller


- Original Message - 
From: "Henrik Nordstrom" 

To: "Markus Moeller" 
Cc: 
Sent: Saturday, March 06, 2010 10:26 AM
Subject: Re: "negotiate" auth with fallback to other schemes



fre 2010-03-05 klockan 20:44 + skrev Markus Moeller:

I don't understand this part. Usually the kdc is on AD so how can NTLM 
work

and Kerberos not ?


The NTLM client just needs the local computer configuration +
credentials entered interactively by the user. All communication with
the AD is indirect via the proxy. The client do not need any form of
ticked before trying to authenticate via NTLM, just the username +
domain + password.

For similar reasons NTLM also do not have any protection from mitm
session theft. Meaning that the auth exchange done to the proxy may just
as well be used by a mitm attacker to authenticate as that client to any
server in the network for any purpose.



So it makes the statement  "Kerberos may fail just because the client
has no connectivity with the KDC, and in this case NTLM could be a
useful second choice" false. Since in the case of NTLM will fail too as
the kdc (AD) is unavailable



Regards
Henrik


Regards
Markus 





Re: "negotiate" auth with fallback to other schemes

2010-03-06 Thread Henrik Nordstrom
fre 2010-03-05 klockan 20:44 + skrev Markus Moeller:

> I don't understand this part. Usually the kdc is on AD so how can NTLM work 
> and Kerberos not ?

The NTLM client just needs the local computer configuration +
credentials entered interactively by the user. All communication with
the AD is indirect via the proxy. The client do not need any form of
ticked before trying to authenticate via NTLM, just the username +
domain + password.

For similar reasons NTLM also do not have any protection from mitm
session theft. Meaning that the auth exchange done to the proxy may just
as well be used by a mitm attacker to authenticate as that client to any
server in the network for any purpose.

Regards
Henrik



Re: "negotiate" auth with fallback to other schemes

2010-03-05 Thread Amos Jeffries

Livio B wrote:

Hi,


In particular, if I want only transparent auth, it wouldn't make sense
to retry the authentication because either the helper would get the
same SSO (denied) credentials or the user would get prompted (which I
don't want). On a different scenario, where it is ok to prompt the
user for alternative credentials, it would make sense to retry the
negotiate.

Yes, and how would the helper know when this is? That knowledge is
better in Squid..


Well that would have to be a parameter to the helper command.
So, to summarize, adding this fall-back option would either require 1)
a backward compatible protocol update, or 2) a backward compatible
auth_param syntax extension.
Option 1) would have the advantage that the helper could behave
differently basing on client responses;
option 2) would have the advantage that it doesn't require changes to helpers.
You are clearly advocating option 2.


This seem a little unflexible. For example, currently there is no
helper that can handle both negotiate/kerberos and negotiate/ntlm so
if I need to support both I need a negotiate helper and a NTLM helper
and might want to disable just one. And of course new protocols can
eventually surface.

Is the flexibility really needed in this case?

Negotiate and NTLM is very closely related, and will always connect to
the same backend (windows ADS / domain controller) at least in sane
setups. If one fails then there is very limited use of trying the other.


This is not completely fair. Kerberos may fail just because the client
has no connectivity with the KDC, and in this case NTLM could be a
useful second choice.


Additionally I as a user and network admin would not be comfortable
with digest auth automatically falling back on basic on authentication
failure, due to the non-existing security of basic auth. If the client
supports digest then it should stick to that until the user says
otherwise.


Agree.

So I'll work on a patch to support a new auth_param option (any
suggested syntax?) and tracking the list of "disabled" protocols in
the "request" or "connection" object, keeping the connection open even
when authentication fails.

Regards,
Livio


All of this discussion sounds a lot like the open feature request to 
make particular authentication schemes AC-based.


That feature would be implementing a configuration something like this:
  auth_param type allow|deny acllist ...

the effect being that it would allow or prevent the auth scheme being 
added to the response headers.


This would allow both what you want (based on helper reply + request 
auth type) and other things like user-agent (dropping negotiate as a 
choice for IE6, or non-basic for Java 1.4) or specific schemes for 
specific LAN networks.


Amos
--
Please be using
  Current Stable Squid 2.7.STABLE7 or 3.0.STABLE24
  Current Beta Squid 3.1.0.17


Re: "negotiate" auth with fallback to other schemes

2010-03-05 Thread Markus Moeller


"Livio B"  wrote in message 
news:31f0d2c51003050619o6d3a78b9uaf319d8e63aa7...@mail.gmail.com...

Hi,


In particular, if I want only transparent auth, it wouldn't make sense
to retry the authentication because either the helper would get the
same SSO (denied) credentials or the user would get prompted (which I
don't want). On a different scenario, where it is ok to prompt the
user for alternative credentials, it would make sense to retry the
negotiate.


Yes, and how would the helper know when this is? That knowledge is
better in Squid..


Well that would have to be a parameter to the helper command.
So, to summarize, adding this fall-back option would either require 1)
a backward compatible protocol update, or 2) a backward compatible
auth_param syntax extension.
Option 1) would have the advantage that the helper could behave
differently basing on client responses;
option 2) would have the advantage that it doesn't require changes to 
helpers.

You are clearly advocating option 2.


This seem a little unflexible. For example, currently there is no
helper that can handle both negotiate/kerberos and negotiate/ntlm so
if I need to support both I need a negotiate helper and a NTLM helper
and might want to disable just one. And of course new protocols can
eventually surface.


Is the flexibility really needed in this case?

Negotiate and NTLM is very closely related, and will always connect to
the same backend (windows ADS / domain controller) at least in sane
setups. If one fails then there is very limited use of trying the other.


This is not completely fair. Kerberos may fail just because the client
has no connectivity with the KDC, and in this case NTLM could be a
useful second choice.


I don't understand this part. Usually the kdc is on AD so how can NTLM work 
and Kerberos not ?





Additionally I as a user and network admin would not be comfortable
with digest auth automatically falling back on basic on authentication
failure, due to the non-existing security of basic auth. If the client
supports digest then it should stick to that until the user says
otherwise.


Agree.

So I'll work on a patch to support a new auth_param option (any
suggested syntax?) and tracking the list of "disabled" protocols in
the "request" or "connection" object, keeping the connection open even
when authentication fails.

Regards,
Livio






Re: "negotiate" auth with fallback to other schemes

2010-03-05 Thread Livio B
Hi,

>> In particular, if I want only transparent auth, it wouldn't make sense
>> to retry the authentication because either the helper would get the
>> same SSO (denied) credentials or the user would get prompted (which I
>> don't want). On a different scenario, where it is ok to prompt the
>> user for alternative credentials, it would make sense to retry the
>> negotiate.
>
> Yes, and how would the helper know when this is? That knowledge is
> better in Squid..

Well that would have to be a parameter to the helper command.
So, to summarize, adding this fall-back option would either require 1)
a backward compatible protocol update, or 2) a backward compatible
auth_param syntax extension.
Option 1) would have the advantage that the helper could behave
differently basing on client responses;
option 2) would have the advantage that it doesn't require changes to helpers.
You are clearly advocating option 2.

>> This seem a little unflexible. For example, currently there is no
>> helper that can handle both negotiate/kerberos and negotiate/ntlm so
>> if I need to support both I need a negotiate helper and a NTLM helper
>> and might want to disable just one. And of course new protocols can
>> eventually surface.
>
> Is the flexibility really needed in this case?
>
> Negotiate and NTLM is very closely related, and will always connect to
> the same backend (windows ADS / domain controller) at least in sane
> setups. If one fails then there is very limited use of trying the other.

This is not completely fair. Kerberos may fail just because the client
has no connectivity with the KDC, and in this case NTLM could be a
useful second choice.

> Additionally I as a user and network admin would not be comfortable
> with digest auth automatically falling back on basic on authentication
> failure, due to the non-existing security of basic auth. If the client
> supports digest then it should stick to that until the user says
> otherwise.

Agree.

So I'll work on a patch to support a new auth_param option (any
suggested syntax?) and tracking the list of "disabled" protocols in
the "request" or "connection" object, keeping the connection open even
when authentication fails.

Regards,
Livio


Re: "negotiate" auth with fallback to other schemes

2010-02-25 Thread Henrik Nordström
ons 2010-02-24 klockan 17:03 +0100 skrev Livio B:

> For example, even when kerberos auth succeeds (AF message), still
> squid acls can deny access to that authenticated user. And the helper
> has no way to know that. Depending on the scenario, it may make sense
> to prompt the user again or not.

That's controlled in http_access.

> In particular, if I want only transparent auth, it wouldn't make sense
> to retry the authentication because either the helper would get the
> same SSO (denied) credentials or the user would get prompted (which I
> don't want). On a different scenario, where it is ok to prompt the
> user for alternative credentials, it would make sense to retry the
> negotiate.

Yes, and how would the helper know when this is? That knowledge is
better in Squid..

> However letting the helper decide seems more dynamic and allows for
> decisions based on the answer from the client, something that wouldn't
> be possible with auth_param.

In reality the helpers don't know much of the auth protocol, just
relaying data to some auth backend.

> Also letting the helper decide wouldn't
> require a change to auth_param syntax (possibly breaking backward
> compatibility)

How would it break backward compatibility? It's a new option. Old
configs without the option will still work the same..

>  tough it clearly requires a small protocol extension.

Which breaks compatibility, and requires each and every helper to get
updated with configuration directives to allow the admin to decide how
the helper should react..

> This seem a little unflexible. For example, currently there is no
> helper that can handle both negotiate/kerberos and negotiate/ntlm so
> if I need to support both I need a negotiate helper and a NTLM helper
> and might want to disable just one. And of course new protocols can
> eventually surface.

Is the flexibility really needed in this case?

Negotiate and NTLM is very closely related, and will always connect to
the same backend (windows ADS / domain controller) at least in sane
setups. If one fails then there is very limited use of trying the other.
Exception is browser bugs, but those are better handled by scheme acls
to block for example the Negotiate scheme for known broken browsers.

Theoretically there may be value in fallback from http digest to http
basic auth in some cases, but neither of those is single-sign-on and in
my experience since those are not SSO to begin with the method of
canceling the first to get to the next one works about as well as we can
get. Additionally I as a user and network admin would not be comfortable
with digest auth automatically falling back on basic on authentication
failure, due to the non-existing security of basic auth. If the client
supports digest then it should stick to that until the user says
otherwise.




Regards
Henrik



Re: "negotiate" auth with fallback to other schemes

2010-02-25 Thread Henrik Nordström
tor 2010-02-25 klockan 11:20 +1300 skrev Amos Jeffries:

> What would be nice is that if the Kerberos libraries received NTLM input
> they should handle it as NTLM instead of immediately rejecting it. When
> that happens the Squid kerberos helper (or an extended one) should be able
> to handle both auth methods without re-challenging.

Negotiate (SPNEGO) is a wrapper around the Windows SSP providers, all of
them, and encapsulates both GSSAPI (Kerberos) and NTLM and a lot more.

Raw Kerberos (GSSAPI) without SPNEGO also exists in Microsoft HTTP in
the form of the Kerberos auth scheme.

This said it should perhaps be mentioned that GSSAPI is also a wrapper,
but without negotiation capabilities.

Regards
Henrik



Re: "negotiate" auth with fallback to other schemes

2010-02-24 Thread Amos Jeffries
On Wed, 24 Feb 2010 17:03:08 +0100, Livio B  wrote:
> 2010/2/23 Henrik Nordström :
>>> 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 would say this fits better as an auth_param setting. Both Negotiate
>> and NTLM protocols has a clear "Authentication has failed due to
invalid
>> credentials" message (NA ).
> 
> Yes however, whether the client should get prompted again can make
> sense (or not) regardless of the type of the returned message (NA, BH,
> AF...).
> For example, even when kerberos auth succeeds (AF message), still
> squid acls can deny access to that authenticated user. And the helper
> has no way to know that. Depending on the scenario, it may make sense
> to prompt the user again or not.
> In particular, if I want only transparent auth, it wouldn't make sense
> to retry the authentication because either the helper would get the
> same SSO (denied) credentials or the user would get prompted (which I
> don't want). On a different scenario, where it is ok to prompt the
> user for alternative credentials, it would make sense to retry the
> negotiate.
> 
>> Why do the helper need to decide if the user should be prompted again?
>> In which cases should the user get prompted again for Negotiate or NTLM
>> after incorrect authentication?
> 
> I'm not sure: at the moment I cannot think of cases where the helper
> decision cannot be taken beforehand as an auth_param.
> However letting the helper decide seems more dynamic and allows for
> decisions based on the answer from the client, something that wouldn't
> be possible with auth_param. Also letting the helper decide wouldn't
> require a change to auth_param syntax (possibly breaking backward

auth_param can be extended without many compatibility worries.

> compatibility) tough it clearly requires a small protocol extension.
> 
>>> 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:
>>
>> Simplest is to add a per-connection flag indicating that connection
>> oriented auth (NTLM / Negotiate) should not be used for this
connection.
> 
> This seem a little unflexible. For example, currently there is no
> helper that can handle both negotiate/kerberos and negotiate/ntlm so
> if I need to support both I need a negotiate helper and a NTLM helper
> and might want to disable just one. And of course new protocols can
> eventually surface.

Whenever NTLM or Kerberos credentials are sent over a TCP connection. The
entire connection (through every single proxy hop along the way) changes
its authentication credentials. These credentials may be spread and cached
across the whole Internet in order to authenticate with one remote server.

All other authentication methods only authenticate a specific part of the
link between a server and client. Credentials are not passed outside the
current administrators security zone.

(You start to see why security people don't like NTLM stuff?)


What would be nice is that if the Kerberos libraries received NTLM input
they should handle it as NTLM instead of immediately rejecting it. When
that happens the Squid kerberos helper (or an extended one) should be able
to handle both auth methods without re-challenging.

If you know of any way thats possible today, please get in touch with
Marcus the negotiate/Kerberos helper author. I know he has a lot of people
annoying him with questions when they inadvertently configure NTLM thinking
its Kerberos.

Amos



Re: "negotiate" auth with fallback to other schemes

2010-02-24 Thread Livio B
2010/2/23 Henrik Nordström :
>> 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 would say this fits better as an auth_param setting. Both Negotiate
> and NTLM protocols has a clear "Authentication has failed due to invalid
> credentials" message (NA ).

Yes however, whether the client should get prompted again can make
sense (or not) regardless of the type of the returned message (NA, BH,
AF...).
For example, even when kerberos auth succeeds (AF message), still
squid acls can deny access to that authenticated user. And the helper
has no way to know that. Depending on the scenario, it may make sense
to prompt the user again or not.
In particular, if I want only transparent auth, it wouldn't make sense
to retry the authentication because either the helper would get the
same SSO (denied) credentials or the user would get prompted (which I
don't want). On a different scenario, where it is ok to prompt the
user for alternative credentials, it would make sense to retry the
negotiate.

> Why do the helper need to decide if the user should be prompted again?
> In which cases should the user get prompted again for Negotiate or NTLM
> after incorrect authentication?

I'm not sure: at the moment I cannot think of cases where the helper
decision cannot be taken beforehand as an auth_param.
However letting the helper decide seems more dynamic and allows for
decisions based on the answer from the client, something that wouldn't
be possible with auth_param. Also letting the helper decide wouldn't
require a change to auth_param syntax (possibly breaking backward
compatibility) tough it clearly requires a small protocol extension.

>> 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:
>
> Simplest is to add a per-connection flag indicating that connection
> oriented auth (NTLM / Negotiate) should not be used for this connection.

This seem a little unflexible. For example, currently there is no
helper that can handle both negotiate/kerberos and negotiate/ntlm so
if I need to support both I need a negotiate helper and a NTLM helper
and might want to disable just one. And of course new protocols can
eventually surface.

Thanks
Livio


Re: "negotiate" auth with fallback to other schemes

2010-02-23 Thread Henrik Nordström
tis 2010-02-23 klockan 14:44 +0100 skrev Livio B:

> 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).

Can do.

> 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).

Correct, as the browser supports Kerberos and NTLM and prefers using
those. Both supports prompting the user for credentials just as basic
does.

> 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 would say this fits better as an auth_param setting. Both Negotiate
and NTLM protocols has a clear "Authentication has failed due to invalid
credentials" message (NA ).

Why do the helper need to decide if the user should be prompted again?
In which cases should the user get prompted again for Negotiate or NTLM
after incorrect authentication?

> 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:

Simplest is to add a per-connection flag indicating that connection
oriented auth (NTLM / Negotiate) should not be used for this connection.

I don't think there is need for more advanced fallback than "only try
Basic is connection oriented auth fails". I don't see any reasonable use
cases where one would want fallback on NTLM is Negotiate fails as the
two is so tightly related.

> One possible solution could be to not force a connection-close after a
> failed authentication (it shouldn't be necessary, should it?).

That's absolutely necessary for this to work out. If the connetion is
dropped then there is no place where to keep track of the state.

Doing it on the IP level is not right, as there may be many users
sharing the same IP (NAT:ed, using an internal proxy, or running on
terminal server or other multi-user server).

>  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.

HTTP auth is done per message.

NTLM & Negotiate is not actually HTTP auth and is done per TCP
connection, while looking seemingly like HTTP auth in the initial
steps..

Regards
Henrik



"negotiate" auth with fallback to other schemes

2010-02-23 Thread Livio B
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