Fixing mod_auth_sspi and IE losing POST data
I think I’ve fixed this IE-loses-POST data bug; I’m seeking feedback, verification and testing from others that want to lend a hand.
- Sources are in my Mercurial repository.
- Download mod_auth_sspi_1.0.5b-2.2.9.zip (beta, updated 2006/6/23)
More binaries are available in my downloads directory.
Important
- requires Apache 2.2.9 (build for Apache 2.2.8 is still available)
- requires Windows XP or Vista w/ the Visual C++ redist installed
- I posted a binary built with Visual Studio 2005; while I cannot get it to load, it may work on Windows 2000. (I don’t have access to any Windows 2000 machines.) You’ll need to VC2005 SP1 redist installed.
- update - zip files has renamed
mod_auth_sspi.so.manifesttohttpd.exe.manifest- this file needs to be in yourApache2\bindirectory if you’re using the Apache binary from apache.org
Unfortunately, since I used the latest Windows SDK, Windows 2000 cannot load this module. Once the changes are officially accepted, we can see about porting to other Windows platforms.
If you’d like me to build against other versions of Apache (on Vista or XP), use this site’s contact form to let me know.
I am interested in getting these changes back into SourceForge, but wanted to hack on my own (with revision control) first, which is why there’s a Mercurial repository. (I’m not trying to fork this project, or anything.)
This module does report itself as mod_auth_sspi 1.0.5 - that not meant to be an official 1.0.5; this is still a beta, and not officially accepted into the SourceForge project yet.
Development Details
I not an Apache or APR guru; I had to learn what was going on from scratch. I spent the first two days just getting familiar with the mod_auth_sspi source, and added a lot of comments along the way.
I eventually found the section where I should check for IE’s unique behavior; I detected its special case and coded a “reset” so that IE gets the re-authentication it is looking for.
Special thanks to all who contributed bits of info in the bug post - that’s what got me started int he right direction to code fix.
The Fix
Essentially, mod_auth_sppi now checks incoming POST requests (on existing connections only) to see if they have a Content-Length of zero.
IE (I think!) only does this when it want to re-authenticate. The module restarts the auth process and IE eventually sends its correct POST with all data. There is no longer a need to always run with per_auth_request ON, and we can save a bit of extra traffic to our web servers and Domain Controller.
Code Changes & Refactoring
I tried, as much as possible, to
- preserve the existing coding style
except I tried to wrap long lines before 80 characters. (Seems like the Apache source code does much the same.) - add comments (in the Doxygen format) liberally, to help out others new to Apache module hacking
- not change any functionality other than what was required for this bug
(one exception: I did change a#defineinmod_auth_sspi.h-DEFAULT_SSPI_PACKAGEis nowNEGOTIATEinstead ofNTLM. (Since both Firefox and IE support Kerberos, I was hoping the change would allow the stronger security method to be chosen. While it doesn’t seem to have broken anything, I have not yet confirmed that Kerberos is being used.)
update - I changed the define back toNTLM- whileNegotiateseemed to work fine on my XP dev machine, trying it on Firefox on W2k3 caused a bunch of 500 errors. (Oddly, IE7 worked fine with it.) Any Kerberos experts want to lend some information?
Install
This module will not work with versions of Apache prior to 2.2.8.
You will need to have the Visual C++ 2008 redist installed on your system or Apache won’t be able to load the module. (If you’re using the vc8 build, you must have the Visual C++ 2005 SP1 redist instead.)
- unzip to contents of the file to a temporary directory of your choice
- test to see if you installed the Visual C++ redist
- open a command prompt in your temporary directory
- run
sspipkgs.exe - you should see a list of all installed SSPI packages on your server (I see 9 on mine)
- copy
mod_auth_sspi.soto yourApache2\modulesdirectory - if using the apache.org MSI binary: copy
httpd.exe.manifesttoApache2\bin - edit your
httpd.conffile to load the module and turn on SSPI auth for a directory
httpd.conf example
LoadModule sspi_auth_module modules/mod_auth_sspi.so
<Directory "C:/webdata/htdocs">
# Configure mod_auth_sspi - who can get stuff from this server.
AuthName "Intranet SSPI"
AuthType SSPI
SSPIAuth On
SSPIAuthoritative On
SSPIOfferBasic On
SSPIDomain MYDOMAIN
SSPIOmitDomain On
SSPIUsernameCase lower
# PerRequestAuth can now be safely set to `off` in 1.0.5
SSPIPerRequestAuth off
require valid-user
</Directory>
How to Build
You can build a production-quality version of this module for yourself using freely available tools and compilers. Download and install the following:
Latest Editions (VC 2008)
These binaries will only load on Windows XP and Vista platforms. I’ll refer to this as VC9.
- download Visual C++ Express 2008
- the latest Windows SDK
- the Visual C++ redist package
- minGW (optional) - this gives you
afxres.h, which is asked for in one of the resource files. You can save yourself a download and just renameafxres.htowindows.hand everything seems to work, but I haven’t tested this much.
Previous Version (VC 2005)
This versions produces binaries compatible with Windows 2000, XP, and Vista(?). I’ll refer to this as VC8.
- download Visual C++ Express 2005
On the download site, click on “Previous Versions” to get the 2005 edition. - the Windows 2003 R2 Platform SDK
If doing a web or custom install, be sure to include the IE SDK to get all of the headers you’ll need. - the Visual C++ 2005 SP1 redist package
- minGW (optional, see above)
Read this note about why using the latest-and-greatest software might not be so great. (I didn’t find that note until after I’d done all of my development work.)
Build local APR
Note the “need to add” steps all apply to VC8 only. VC9 seems to have them already set okay.
- Start your Visual C++ IDE
- open
httpd-2.2.8\srclib\apr-util\aprutil.dsw- go to
Tools > Options > Projects and Solutions > VC++ Directories- add your
SDK\Includedirectory toInclude files - add your
SDK\Libdirectory toLibrary Files
- add your
- go to
- set your build type to
ReleaseorReleaseNT(I usedReleaseNT) - build
apr - build
aprutil - build
libapr(need to addadvapi32.libto the project’sProperties > Configuration > Linker > Input) - build
libaprutil(need to addlibexpat.libfrom expat. Again, add it to your Linker Input list and add the directory of the.libfile to your Library Files include paths - do
File > Close Solution
Build local libhttpd
- open
Apache.dswin yourhttpd-2.2.8source directory. - build
libapr- (need to add
Shell32.libto theProperties > Config Properties > Linker > Inputlist)
- (need to add
- build
libaprutil - build
libhttpd- need to add
advapi32.lib(for security functions) to your Linker again - need to add
user32.lib(for threading functions) - You’ll get a compiler error on
httpd.rc- this is due to invalid quote nesting the build script. Look at the details build log (html file), drop into the VC command line build environment, and correct the quotes to compile the file yourself. Then use the VC IDE to resume building.- Example:
/d "LONG_NAME="Apache HTTP Server Core""should really be/d "LONG_NAME=Apache HTTP Server Core"
- Example:
- need to add
Close the VC IDE - you’re done with it for now. (And honestly, I’m not sure how many of these build steps are truly needed - this is just an account of what worked for me.)
Build mod_auth_sspi
Next I’d recommend using Mercurial to get the source from my repository.
hg clone http://dev.nosq.com/repos.hg/mod_auth_sspi/
You’ll need to edit the Makefile so that the first 5 define lines point to the right directories in your environment.
After that,
- start the “Visual Studio 200x Command Prompt”,
cdto your Mercurial repository, and- type
nmake.- you may need to adjust the
AP_LIBPATHline so that\srclib\apr\Releasebecomes\srclib\apr\NT\Releaseif you built usingReleaseNTinstead ofReleasein your build settings, above
- you may need to adjust the
If everything went well, you should have a .\bin directory with the newly built .so.
Updated using VC8
I went through and re-built using VC8 (Visual C++ 2005). It worked when I used the Apache binary from httpd.apache.org and included the httpd.exe.manifest file in the Apache2\bin directory.
Otherwise, when using the ApacheLounge binary, I got
httpd: Syntax error on line 127 of C:/dev/webservices/Apache2/conf/httpd.conf: Cannot
load C:/dev/webservices/Apache2/modules/mod_auth_sspi.so into server: A dynamic
link library (DLL) initialization routine failed.
when I ran httpd -t.
Great! At last!
Thanks!
I have been looking all over the place to solve this exact problem. Am running Apache 2.2.6 and cannot upgrade at this time. Do you know where a patched mod_auth_sspi.so can be found that will fix this IE prob w/ Apache 2.2.6? I’ve tried just about everything, would appreciate any suggestions or guidance. Thanks.