The NTLM authentication project aims at providing Microsoft NTLM proxy authentication support for Squid.
The implementation I have (authenticator module only right now) implements a simple text based protcol that (a) passes basic intialisation information (b) does authentication queries, as you'd expect and (c) allows the authenticator module to track connection state for the benefit of authentication methods that require handshaking.
It's implemented using a library (libauth) that provides the foundation. The actual authenticator module code provides 3 methods - open(), close() and query(), making it pretty simple to write to.
I'm not clear on how this would affect performance
NTLM authentication is proxyable provided the client is willing to do NTLM WWW authentication through a proxy, there are two basic reasons I can think of: Squid isn't passing the authentication info correctly (i.e. all messages should be during 1 persistant connection for each authentication attempt) or IIS is checking the workstation/domain name.
I've managed a couple of FreeBSD firewals before and seen a lot of WINS queries directed at them. I don't know if it's related.
If I had the time I'd personally follow this through, but I'm working 13 hour days right now. Proxy authentication is a small part of that though.
Note from Henrik: It can. There is noting in NTLM authentication which makes it impossible to proxy, besides the fact that it requires a single persistent connection client<->origin server, with any number of proxies/tunnels in between. There is a very notable collision between RFC 2616 and MS NTLM authentication in that RFC 2616 advocates that client<->proxy and proxy<->origin connections are more or less independent by each other, while MS NTLM requires them to be tightly coupled as one connection.
I have now got a fair understanding of the NTLM authentication sheme. Next step would be to figure out how to correctly fit this in Squid...
One approach would be to simply add the NTLM+RPC code to Squid, but it is a fairly large chunk of code needed, and I am not aware of any non-blocking implementation of the DCE-RPC (or whatever the RPC used by SMB/LM/CIFS is called) freely available.
The approach I am leaning towards is some more generalized approach to authentication with (for NTLM) sticky authenticators on a per client connection basis. The idea is to find a authenticator module method suitable for all three commonly used authentication methods (Basic, Digest, NTLM). Squid should only concern itself with the minimal decoding required to find the username, and caching of authentication responses. The rest should be handed off to the authenticator (probably as-is). I have yet to study some of the details of Digest authentication to find out what requirements that makes on Squid, so this picture may be slightly revised..
There is also need for a user-group concept. In some cases this can be joined with the authenticator, in other cases the need is separately on a per group basis. What I am leaning towards on this issue is to have two acl types:
auth_group: Membership indicated by the authenticator process.
group: Membership queried by a per group+username(or ident)+ip basis wia external helpers.
A third concept missing from Squid is divided user spaces, where one segment of the network is one domain of users and another segment is another domain of users. The way I see this solved is to add a authentication class directive, and have the authentication made and cached within that class.
auth_class company1 src 10.0.1.0/24 192.168.1.0/24
auth_class company2 src 10.0.2.0/25 192.168.2.0/24
This can also be generalized to have classes where authentication is
unique on a IP basis
auth_class specialclass* src 192.168.3.0/24
where speciallclass* is a psuedo class with one unique class per IP within that range, all named specialclass in access checks outside the authentication.
The one ip per user limit I introduced earlier would be effective within each unique auth_class.
NTML is a bit different and does not obey the standard rules of HTTP connection management. The authentication is a three step (5 way) handshake per TCP connection, not per request.
1a. Client sends unauthenticated request to the proxy / server.
1b. Proxy / server responds with "Authentication required" of type NTLM.
2a. The client responds with a request for NTLM negotiation
2b. The server responds with a NTLM challenge
3a. The client responds with a NTLM response
3b. if successful the connection is authenticated for this request and onwards. No further authentication exchanges takes place on THIS TCP connection.
From step 2 and onwards the connection MUST be persistent, or the whole thing has to start over from the beginning. The response in step 1 does not need to keep the connection persistent. However, as it still must eat any request body it might just as well keep the connection persistent all the way, unless there is a compability problem with other browsers preventing this.