Re: [squid-dev] [PATCH] add support for using an existing kerberos cache instead of a keytab
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
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
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
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
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
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
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