Re: NTLM patch

From: Henrik Nordstrom <hno@dont-contact.us>
Date: Mon, 24 Jan 2000 20:41:19 +0100

Duane Wessels wrote:

> Eating the message body is fine. I was more referring to the ugly part
> of scanning for newlines and looking for words that seem to be
> request methods.

Ok, you are referring to that last code snippet..

I haven't looked into what that mess of a hack does. It does not look
like it is doing the "right" thing there. The function required by Squid
is far from a mess, and no guessing of any form is required.

> Can't we send connection: close on the "auth required" reply? There
> should be a subsequent request already on the socket only when the
> client is pipelining.

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.

> Doesn't 8.1.2.2 of RFC2616 come into play in the case where
> Squid resets a connection like this? The client should
> retry its request.

Squid is not allowed to cause TCP resets. It SHOULD eat message bodies
and do graceful shutdown of connections eating any additional data
(including new requests) arriving until the connection is closed by the
client.

Clients are supposed to retry the connection if it is closed before
receiving a reply. However a TCP reset is not a close, it is a error
condition indicating that the server has ABORTED the connection.

A TCP CLOSE is the shutdown of the send channel. The receive channel is
open until the other end closes, or the connection is aborted. TCP
applications are allowed to continue reading from the TCP channel even
after they have initiated the CLOSE operation. This is very different
from the BSD Sockets close() operation which shuts down communication
both-ways.

A TCP CLOSE operation is more like

   write(fd) the last message content
   shutdown(fd,1);
   while(read(fd) != 0) {
        process received data (and handle error conditions)
   }
   close(fd);

and you need to keep this in mind while reading RFCs which assumes the
RFC definition of CLOSE. (however, it is a bit unclear which definition
RFC2616 assumes..)

This is also why I say that HTTP does not allow half-closed connections.
Doing so is a contradition to the fact that both the server and client
are supposed to abort as soon as they detect that the other end has
closed the connection to avoid uneccesary network resource drain.

RFC2616 Section 8.1.4 "Practical Considerations", paragraph 2:

   When a client or server wishes to time-out it SHOULD issue a graceful
   close on the transport connection. Clients and servers SHOULD both
   constantly watch for the other side of the transport close, and
   respond to it as appropriate. If a client or server does not detect
   the other side's close promptly it could cause unnecessary resource
   drain on the network.

More relevant to this discussion:

RFC2616 Section 10.4 "Client Error 4xx", last paragraph:

   If the client is sending data, a server implementation using TCP
   SHOULD be careful to ensure that the client acknowledges receipt of
   the packet(s) containing the response, before the server closes the
   input connection. If the client continues sending data to the server
   after the close, the server's TCP stack will send a reset packet to
   the client, which may erase the client's unacknowledged input buffers
   before they can be read and interpreted by the HTTP application.

which is somewhat misleading as the data must have been read by the
client application, not only acknowledged by the TCP stack. To guarantee
the above you must continue reading until the client closes the
connection.

/Henrik
Received on Mon Jan 24 2000 - 12:44:55 MST

This archive was generated by hypermail pre-2.1.9 : Tue Dec 09 2003 - 16:12:20 MST