May 2002 Blog Posts

I heard back from MS support to the effect of the following: it isn't possible to hold the connection open using SF_STATUS_REQ_FINISHED_KEEP_CONN before the page actually starts processing. This means that responding to SF_NOTIFY_PREPROC_HEADERS or SF_NOTIFY_AUTH_COMPLETE will always close the connection regardless. What they also told me, which was the original reason for playing with this, is that "it will not [therefore] be possible to [implement custom NTLM] with IIS 5.x [and] that you will need to use IIS 5's NTLM implementation if you want to use NTLM."

This was all a little bit disappointing.

We finally found a solution to the PNG problem we were having when printing from Internet Explorer. A company that I'm doing some work for have a system that produces a PNG file containing bar codes, which is sent via HTTP to Internet Explorer from where the user can then print the image. While this worked fine on NT4, on Win2000 and WinXP, we were getting fuzzy printing, and Microsoft PSS were unhelpful. We finally found that the PNG files were being generated with a bit depth of 32 and that IE presumably thought this meant it might be a photo and it ought to do some processing on it to give a good print result (printing from other apps such as Paint gave perfect results and we tried different print drivers, etc. with IE). By converting the PNG to a simple monochrome image, IE leaves well alone and we get a correct result.
I received my copies of Refactoring and Design Patterns from Amazon at the end of last week. Just need to find the time to read them now - after I've finished reading Kent Beck's Extreme Programming Explained that I'm about two thirds of the way through (and the pile of reading material building up on my desk).

I spent a while trying to make an ISAPI filter that would perform the NTLM challenge/response handshake with Internet Explorer. Why? Well, apart from wanting to find out more about how the authentication process works, this would allow the authentication to occur without IIS then impersonating that user. In addition, you could add control with the filter without needing to worry about setting NTFS permissions on files and folders.

I ran into a problem though, and I'm sure it is my ISAPI code rather than my NTLM code causing the problem.

Here's what happens:

The first request comes in and I check for an Authorization: header. Since there isn't one, I send back a 401 with a WWW-Authenticate: header asking for NTLM and close the connection.

The second request comes in on a new connection as planned with an Authorization: header with NTLM and the base 64 encoded token. I hook up AcceptSecurityContext and receive SEC_I_CONTINUE_NEEDED as expected so I create a new WWW-Authenticate: header with the base 64 encoded token for the challenge. I send this back with a 401 and ask for the connection to be kept open (SF_STATUS_REQ_FINISHED_KEEP_CONN). I think this is where it goes wrong.

The next request comes in on the same connection with the NTLM response in the Authorization: header, but my filter never sees it. I can see the response from Internet Explorer by monitoring the TCP port with tcpTrace, but I think something has gone wrong with the connection by then.

What should happen is that I will get the NTLM response, again call AcceptSecurityContext and this time I should get SEC_E_OK whereupon I know that I am authenticated, I can set my custom HTTP header, and also set a flag so that I know any subsequent requests on the same connection are preauthenticated.

I've made the source code available  here in case somebody can spot what I've done wrong (it's a VS.NET project but that's only really important in so far as I used an ATL Server include for the base 64 coding).

If you spot what is wrong or have any clues, please get in touch.