Re: [squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab

2015-12-22 Thread Amos Jeffries
On 10/11/2015 12:52 a.m., aymericvincent wrote:
> Hi,
> 
> "Amos Jeffries" writes:
> 
>> > Can we have an updated patch to audit please?
> Sure, here's an updated patch which provides the auth-no-keytab keyword and 
> makes the bit percolate through to the peer proxy connection.
> 
> Tested and working for me.
> 
> Best regards,
>  Aymeric


Applied to Squid-4 as rev.14458.

Sorry for the delay, this should have been applied weeks ago.

Amos

___
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev


Re: [squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab

2015-11-09 Thread aymericvincent

Hi,

"Amos Jeffries"  writes:

> Can we have an updated patch to audit please?

Sure, here's an updated patch which provides the auth-no-keytab keyword and 
makes the bit percolate through to the peer proxy connection.

Tested and working for me.

Best regards,
 Aymeric
=== modified file 'src/CachePeer.h'
--- src/CachePeer.h	2015-03-23 10:20:17 +
+++ src/CachePeer.h	2015-11-09 09:14:36 +
@@ -119,6 +119,7 @@
 #if PEER_MULTICAST_SIBLINGS
 bool mcast_siblings;
 #endif
+bool auth_no_keytab;
 } options;
 
 int weight;

=== modified file 'src/FwdState.cc'
--- src/FwdState.cc	2015-10-27 03:45:40 +
+++ src/FwdState.cc	2015-11-09 09:45:50 +
@@ -964,11 +964,13 @@
 ++ serverConnection()->getPeer()->stats.fetches;
 request->peer_login = serverConnection()->getPeer()->login;
 request->peer_domain = serverConnection()->getPeer()->domain;
+request->flags.auth_no_keytab = serverConnection()->getPeer()->options.auth_no_keytab;
 httpStart(this);
 } else {
 assert(!request->flags.sslPeek);
 request->peer_login = NULL;
 request->peer_domain = NULL;
+request->flags.auth_no_keytab = 0;
 
 switch (request->url.getScheme()) {
 #if USE_OPENSSL

=== modified file 'src/RequestFlags.h'
--- src/RequestFlags.h	2015-01-13 07:25:36 +
+++ src/RequestFlags.h	2015-11-09 09:14:36 +
@@ -30,6 +30,8 @@
 bool ims :1;
 /** request is authenticated */
 bool auth :1;
+/** do not use keytabs for peer Kerberos authentication */
+bool auth_no_keytab :1;
 /** he response to the request may be stored in the cache */
 bool cachable :1;
 /** the request can be forwarded through the hierarchy */

=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc	2015-11-04 16:42:55 +
+++ src/cache_cf.cc	2015-11-09 09:39:40 +
@@ -2165,6 +2165,8 @@
 } else if (!strncmp(token, "login=", 6)) {
 p->login = xstrdup(token + 6);
 rfc1738_unescape(p->login);
+} else if (!strcmp(token, "auth-no-keytab")) {
+p->options.auth_no_keytab = 1;
 } else if (!strncmp(token, "connect-timeout=", 16)) {
 p->connect_timeout = xatoi(token + 16);
 } else if (!strncmp(token, "connect-fail-limit=", 19)) {

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2015-11-05 15:50:04 +
+++ src/cf.data.pre	2015-11-09 09:14:36 +
@@ -3175,6 +3175,12 @@
 			Default is auto to automatically determine the status
 			of the peer.
 	
+	auth-no-keytab
+			Do not use a keytab to authenticate to a peer when
+			login=NEGOTIATE is specified. Let the GSSAPI
+			implementation determine which already existing
+			credentials cache to use instead.
+	
 	
 	 SSL / HTTPS / TLS OPTIONS 
 	

=== modified file 'src/http.cc'
--- src/http.cc	2015-10-15 02:52:58 +
+++ src/http.cc	2015-11-09 09:14:36 +
@@ -1722,10 +1722,15 @@
 if (strncmp(request->peer_login, "NEGOTIATE",strlen("NEGOTIATE")) == 0) {
 char *Token=NULL;
 char *PrincipalName=NULL,*p;
+int negotiate_flags = 0;
+
 if ((p=strchr(request->peer_login,':')) != NULL ) {
 PrincipalName=++p;
 }
-Token = peer_proxy_negotiate_auth(PrincipalName, request->peer_host);
+if (request->flags.auth_no_keytab) {
+negotiate_flags |= PEER_PROXY_NEGOTIATE_NOKEYTAB;
+}
+Token = peer_proxy_negotiate_auth(PrincipalName, request->peer_host, negotiate_flags);
 if (Token) {
 httpHeaderPutStrf(hdr_out, header, "Negotiate %s",Token);
 }

=== modified file 'src/peer_proxy_negotiate_auth.cc'
--- src/peer_proxy_negotiate_auth.cc	2015-04-21 04:50:22 +
+++ src/peer_proxy_negotiate_auth.cc	2015-11-09 09:14:36 +
@@ -499,7 +499,7 @@
  * peer_proxy_negotiate_auth gets a GSSAPI token for principal_name
  * and base64 encodes it.
  */
-char *peer_proxy_negotiate_auth(char *principal_name, char *proxy) {
+char *peer_proxy_negotiate_auth(char *principal_name, char *proxy, int flags) {
 int rc = 0;
 OM_uint32 major_status, minor_status;
 gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
@@ -517,16 +517,18 @@
 return NULL;
 }
 
-if (principal_name)
-debugs(11, 5,
-   HERE << "Creating credential cache for " << principal_name);
-else
-debugs(11, 5, HERE << "Creating credential cache");
-rc = krb5_create_cache(NULL, principal_name);
-if (rc) {
-debugs(11, 5, HERE << "Error : Failed to create Kerberos cache");
-krb5_cleanup();
-return NULL;
+if (!(flags & PEER_PROXY_NEGOTIATE_NOKEYTAB)) {
+if (principal_name)
+debugs(11, 5,
+   HERE << "Creating credential cache for " << principal_name);
+else
+debugs(11, 5, HERE << "Creating credential cache");
+rc = krb5_create_cache(NULL, principal_name);
+if (rc) {
+

Re: [squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab

2015-11-03 Thread Amos Jeffries
I've asked Markus our Kerberos developer;

On 1/11/2015 6:24 a.m., Markus Moeller wrote:
> Hi Amos,
>
>   I looked at the patch and it seems fine.   The user just has to know
> when to renew the cache.
>
> Markus
>

I still think we should have a separate auth-no-keytab flag though.
Besides the reasons I outlined earlier (below) it can be used to
document on squid.conf the conditions of use for the flag separate from
NEGOTIATE as a whole.

Can we have an updated patch to audit please?

Amos


On 23/10/2015 4:22 a.m., Amos Jeffries wrote:
> On 23/10/2015 3:59 a.m., aymericvincent wrote:
>>
>> Hi,
>>
>> "Amos Jeffries" writes:
>>
>>> This patch appears to make Squid ignore loading keytabs entirely and
>>> just allow random credentials from unspecified location(s) to be used.
>>
>> That's correct and that's the whole point of the diff. ("unspecified 
>> location"... to squid)
>>
>>> In the absence of a location from which to load the credentials where
>>> does GSSAPI load the credentials from?
>>
>> When a user is logged in and authenticated to a kdc, a credentials cache is 
>> kept around (in practice in a file belonging to the user in /tmp on Unix) 
>> and used whenever kerberos authentication is required by a client. That's 
>> what you see when you type "klist" for example. Given that one of the 
>> interesting features of kerberos is single sign on, I would be surprised 
>> that the behaviour is not very similar on other OSes/implementations.
>>
>>> Is the users generic cache backed by a keytab somewhere in the local
>>> account? and why can't we just load that?
>>
>> I'm not familiar enough with kerberos to be authoritative, but I'm quite 
>> sure it's not the case : the ticket granting ticket is provided in exchange 
>> for the user's password, not thanks to a user-specific keytab AFAIK.
>>
>>> Overall this seems to me to be making Squid pick a random user account
>>> from the machine and sending a lot of traffic through some peer
>>> pretending to be that user instead of a proxy. That is bad security, and
>>> Kerberos is supposed to be the most secure authentication possible. So I
>>> am not happy with this (yet).
>>
>> I'm fine with your opinion, but you should replace "a random user account" 
>> by "the account which started squid".
> 
> I'm not sure even that is true. Because Squid dynamically alters its
> user account for the workers. They may be running as some other
> effective user with a different credentials cache.
> 
> Which reminds me that Squid usually cannot be started by a non-root user
> anyway. There are root privileges required to do effective-user changes,
> capabilities assignment, access kernel NAT tables and some other socket
> operations we do.
> 
>>
>>> NP: don't worry about small diff. We are in feature freeze for Squid-4
>>> beta cycle. Since this is a small UI change it will be held anyway until
>>> Squid-5 branching, which is likely to be a month or two away.
>>
>> OK, I'll keep that in mind. So we can devise a better way of specifying the 
>> option. Moreover, I also realised that keeping the ability to specify a 
>> principal name in the NOKEYTAB case is pointless (and will be ignored by the 
>> current code) so if others prefer to keep a similar syntax (I'm not fond of 
>> it either), it could be login=NEGOTIATE:NOKEYTAB directly and not 
>> login=NEGOTIATE::NOKEYTAB.
>>
> 
>  "login=NEGOTIATE auth-no-keytab" should do.
> 
> Like I mentioned that allows a simple boolean flag in the CachePeer.
> Which avoids the macro define. And also adjusting the if conditions in
> all the places auth type is detected by those nasty strcmp/strncmp tests.
> 
> Amos
> ___
> squid-dev mailing list
> squid-dev@lists.squid-cache.org
> http://lists.squid-cache.org/listinfo/squid-dev
> 

___
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev


Re: [squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab

2015-10-22 Thread aymericvincent

Hi,

"Amos Jeffries"  writes:

> This patch appears to make Squid ignore loading keytabs entirely and
> just allow random credentials from unspecified location(s) to be used.

That's correct and that's the whole point of the diff. ("unspecified 
location"... to squid)

> In the absence of a location from which to load the credentials where
> does GSSAPI load the credentials from?

When a user is logged in and authenticated to a kdc, a credentials cache is 
kept around (in practice in a file belonging to the user in /tmp on Unix) and 
used whenever kerberos authentication is required by a client. That's what you 
see when you type "klist" for example. Given that one of the interesting 
features of kerberos is single sign on, I would be surprised that the behaviour 
is not very similar on other OSes/implementations.

> Is the users generic cache backed by a keytab somewhere in the local
> account? and why can't we just load that?

I'm not familiar enough with kerberos to be authoritative, but I'm quite sure 
it's not the case : the ticket granting ticket is provided in exchange for the 
user's password, not thanks to a user-specific keytab AFAIK.

> Overall this seems to me to be making Squid pick a random user account
> from the machine and sending a lot of traffic through some peer
> pretending to be that user instead of a proxy. That is bad security, and
> Kerberos is supposed to be the most secure authentication possible. So I
> am not happy with this (yet).

I'm fine with your opinion, but you should replace "a random user account" by 
"the account which started squid".

> NP: don't worry about small diff. We are in feature freeze for Squid-4
> beta cycle. Since this is a small UI change it will be held anyway until
> Squid-5 branching, which is likely to be a month or two away.

OK, I'll keep that in mind. So we can devise a better way of specifying the 
option. Moreover, I also realised that keeping the ability to specify a 
principal name in the NOKEYTAB case is pointless (and will be ignored by the 
current code) so if others prefer to keep a similar syntax (I'm not fond of it 
either), it could be login=NEGOTIATE:NOKEYTAB directly and not 
login=NEGOTIATE::NOKEYTAB.

Best regards,
 Aymeric
___
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev


Re: [squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab

2015-10-22 Thread Amos Jeffries
On 23/10/2015 2:30 a.m., aymericvincent wrote:
> 

> Hi,
> 
> the attached patch adds a NOKEYTAB option to the login=NEGOTIATE case
> (a local proxy needs to authenticate via kerberos to a proxy peer).
> 
> When specified, this option prevents squid from crafting a kerberos
> credentials cache from a keytab, but instead lets GSSAPI use an
> existing credentials cache.
> 
> This is very useful to allow a normal user to use his user
> credentials to run a local unprivileged squid on his desktop/laptop
> without having to deploy a keytab on the (say) parent proxy.
> 
> The way the option is specified is IMHO sub-optimal (sorry) but
> minimises diff footprint, and I'm open to any suggestion if you're
> interested in incorporating this simple yet useful change.
> 

There are two existing Negotiate auth cases.

* One where a "login=NEGOTIATE:principle_name" is given and causes Squid
to load the named entry from the users keytab.

* One where only "login=NEGOTIATE" is given, and causes Squid to load
the default (first) entry from the users default keytab.

In both cases the keytab entry can specify a memory cache contains the
credentials, or a specific named account. But that is stored in the
keytab itself. Not in squid.conf settings.

This patch appears to make Squid ignore loading keytabs entirely and
just allow random credentials from unspecified location(s) to be used.

In the absence of a location from which to load the credentials where
does GSSAPI load the credentials from?

Is the users generic cache backed by a keytab somewhere in the local
account? and why can't we just load that?

Is that GSSAPI behaviour consistent across the four krb5 libraries Squid
can be built to use?


Overall this seems to me to be making Squid pick a random user account
from the machine and sending a lot of traffic through some peer
pretending to be that user instead of a proxy. That is bad security, and
Kerberos is supposed to be the most secure authentication possible. So I
am not happy with this (yet).

Whatever we end up with Squid should never be impersonating a user
account. Ever. It is an automated service, not a person.



NP: don't worry about small diff. We are in feature freeze for Squid-4
beta cycle. Since this is a small UI change it will be held anyway until
Squid-5 branching, which is likely to be a month or two away.

IMO if accepted this should be a separate flag option available on
cache_peer. It would then be a boolean value in the CachePeer object
instead of a global macro #define.

Amos
___
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev


[squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab

2015-10-22 Thread aymericvincent

Hi,

the attached patch adds a NOKEYTAB option to the login=NEGOTIATE case (a local 
proxy needs to authenticate via kerberos to a proxy peer).

When specified, this option prevents squid from crafting a kerberos credentials 
cache from a keytab, but instead lets GSSAPI use an existing credentials cache.

This is very useful to allow a normal user to use his user credentials to run a 
local unprivileged squid on his desktop/laptop without having to deploy a 
keytab on the (say) parent proxy.

The way the option is specified is IMHO sub-optimal (sorry) but minimises diff 
footprint, and I'm open to any suggestion if you're interested in incorporating 
this simple yet useful change.

Best regards,
 Aymeric
=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2015-10-11 14:08:47 +
+++ src/cf.data.pre	2015-10-22 12:59:54 +
@@ -3168,6 +3168,16 @@
 			clients. Negotiate often assumes end-to-end authentication
 			and a single-client. Which is not strictly true here.
 	
+	login=NEGOTIATE:principal_name:NOKEYTAB
+			If this is a personal/workgroup proxy and your parent
+			requires a secure proxy authentication. 
+			The principal principal_name from the default ticket
+			cache or other means provided by GSSAPI will be used.
+	
+			WARNING: The connection may transmit requests from multiple
+			clients. Negotiate often assumes end-to-end authentication
+			and a single-client. Which is not strictly true here.
+	
 	connection-auth=on|off
 			Tell Squid that this peer does or not support Microsoft
 			connection oriented authentication, and any such

=== modified file 'src/http.cc'
--- src/http.cc	2015-10-15 02:52:58 +
+++ src/http.cc	2015-10-22 13:01:18 +
@@ -1721,14 +1721,33 @@
 #if HAVE_AUTH_MODULE_NEGOTIATE && HAVE_KRB5 && HAVE_GSSAPI
 if (strncmp(request->peer_login, "NEGOTIATE",strlen("NEGOTIATE")) == 0) {
 char *Token=NULL;
-char *PrincipalName=NULL,*p;
+char *PrincipalName=NULL,*p,*pOpt;
+int negotiate_flags = 0;
+size_t PrincipalNameLen;
+
 if ((p=strchr(request->peer_login,':')) != NULL ) {
-PrincipalName=++p;
+++p;
+if ((pOpt = strchr(p, ':')) != NULL) {
+++pOpt;
+if (strcmp(pOpt, "NOKEYTAB") == 0)
+negotiate_flags |= PEER_PROXY_NEGOTIATE_NOKEYTAB;
+PrincipalNameLen = (size_t) (pOpt - p - 1);
+} else {
+PrincipalNameLen = strlen(p);
+}
+
+if (PrincipalNameLen != 0) {
+PrincipalName = (char*)xmalloc(PrincipalNameLen + 1);
+strncpy(PrincipalName, p, PrincipalNameLen);
+PrincipalName[PrincipalNameLen] = '\0';
+}
 }
-Token = peer_proxy_negotiate_auth(PrincipalName, request->peer_host);
+Token = peer_proxy_negotiate_auth(PrincipalName, request->peer_host, negotiate_flags);
 if (Token) {
 httpHeaderPutStrf(hdr_out, header, "Negotiate %s",Token);
 }
+if (PrincipalName != NULL)
+xfree(PrincipalName);
 return;
 }
 #endif /* HAVE_KRB5 && HAVE_GSSAPI */

=== modified file 'src/peer_proxy_negotiate_auth.cc'
--- src/peer_proxy_negotiate_auth.cc	2015-04-21 04:50:22 +
+++ src/peer_proxy_negotiate_auth.cc	2015-10-22 12:47:32 +
@@ -499,7 +499,7 @@
  * peer_proxy_negotiate_auth gets a GSSAPI token for principal_name
  * and base64 encodes it.
  */
-char *peer_proxy_negotiate_auth(char *principal_name, char *proxy) {
+char *peer_proxy_negotiate_auth(char *principal_name, char *proxy, int flags) {
 int rc = 0;
 OM_uint32 major_status, minor_status;
 gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
@@ -517,16 +517,18 @@
 return NULL;
 }
 
-if (principal_name)
-debugs(11, 5,
-   HERE << "Creating credential cache for " << principal_name);
-else
-debugs(11, 5, HERE << "Creating credential cache");
-rc = krb5_create_cache(NULL, principal_name);
-if (rc) {
-debugs(11, 5, HERE << "Error : Failed to create Kerberos cache");
-krb5_cleanup();
-return NULL;
+if (!(flags & PEER_PROXY_NEGOTIATE_NOKEYTAB)) {
+if (principal_name)
+debugs(11, 5,
+   HERE << "Creating credential cache for " << principal_name);
+else
+debugs(11, 5, HERE << "Creating credential cache");
+rc = krb5_create_cache(NULL, principal_name);
+if (rc) {
+debugs(11, 5, HERE << "Error : Failed to create Kerberos cache");
+krb5_cleanup();
+return NULL;
+}
 }
 
 service.value = (void *) xmalloc(strlen("HTTP") + strlen(proxy) + 2);

=== modified file 'src/peer_proxy_negotiate_auth.h'
--- src/peer_proxy_negotiate_auth.h	2015-01-13 07:25:36 +
+++ src/peer_proxy_negotiate_auth.h	2015-10-22 12:10:42 +
@@ -10,8 +10,11 @@
 #define SQUID_PEER_PROXY_NEGOTIATE_AUTH_H_
 
 #if 

Re: [squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab

2015-10-22 Thread Amos Jeffries
On 23/10/2015 3:59 a.m., aymericvincent wrote:
> 
> Hi,
> 
> "Amos Jeffries" writes:
> 
>> This patch appears to make Squid ignore loading keytabs entirely and
>> just allow random credentials from unspecified location(s) to be used.
> 
> That's correct and that's the whole point of the diff. ("unspecified 
> location"... to squid)
> 
>> In the absence of a location from which to load the credentials where
>> does GSSAPI load the credentials from?
> 
> When a user is logged in and authenticated to a kdc, a credentials cache is 
> kept around (in practice in a file belonging to the user in /tmp on Unix) and 
> used whenever kerberos authentication is required by a client. That's what 
> you see when you type "klist" for example. Given that one of the interesting 
> features of kerberos is single sign on, I would be surprised that the 
> behaviour is not very similar on other OSes/implementations.
> 
>> Is the users generic cache backed by a keytab somewhere in the local
>> account? and why can't we just load that?
> 
> I'm not familiar enough with kerberos to be authoritative, but I'm quite sure 
> it's not the case : the ticket granting ticket is provided in exchange for 
> the user's password, not thanks to a user-specific keytab AFAIK.
> 
>> Overall this seems to me to be making Squid pick a random user account
>> from the machine and sending a lot of traffic through some peer
>> pretending to be that user instead of a proxy. That is bad security, and
>> Kerberos is supposed to be the most secure authentication possible. So I
>> am not happy with this (yet).
> 
> I'm fine with your opinion, but you should replace "a random user account" by 
> "the account which started squid".

I'm not sure even that is true. Because Squid dynamically alters its
user account for the workers. They may be running as some other
effective user with a different credentials cache.

Which reminds me that Squid usually cannot be started by a non-root user
anyway. There are root privileges required to do effective-user changes,
capabilities assignment, access kernel NAT tables and some other socket
operations we do.

> 
>> NP: don't worry about small diff. We are in feature freeze for Squid-4
>> beta cycle. Since this is a small UI change it will be held anyway until
>> Squid-5 branching, which is likely to be a month or two away.
> 
> OK, I'll keep that in mind. So we can devise a better way of specifying the 
> option. Moreover, I also realised that keeping the ability to specify a 
> principal name in the NOKEYTAB case is pointless (and will be ignored by the 
> current code) so if others prefer to keep a similar syntax (I'm not fond of 
> it either), it could be login=NEGOTIATE:NOKEYTAB directly and not 
> login=NEGOTIATE::NOKEYTAB.
> 

 "login=NEGOTIATE auth-no-keytab" should do.

Like I mentioned that allows a simple boolean flag in the CachePeer.
Which avoids the macro define. And also adjusting the if conditions in
all the places auth type is detected by those nasty strcmp/strncmp tests.

Amos
___
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev