mguessan / davmail

DavMail POP/IMAP/SMTP/Caldav/Carddav/LDAP Exchange and Office 365 Gateway - Synced with main subversion repository at
http://davmail.sourceforge.net
GNU General Public License v2.0
558 stars 82 forks source link

NTLM authentication fails when Extended Protection is enabled server-side #352

Closed teake closed 1 month ago

teake commented 1 month ago

When Extended Protection is enabled on IIS, DavMail cannot successfully complete an NTLM handshake. After the last negotiate message the server sends back a 401 response. See also the attached logs [1]. I've compared the decoded NTLM headers sent by DavMail to those sent by Chrome (which does authenticate successfully), and there is no structural difference. Swapping out the custom JCIFS NTLM implementation with the one with provided natively by HttpClient doesn't help.

This problem is similar to https://github.com/curl/curl/issues/12511, so I'm guessing the HTTP client doesn't set up GSSAPI channel binding properly.

[1] davmail.log

ldoub commented 1 month ago

Are you sure there is no difference in NTLM headers between DavMail and Chrome ? Your problem looks similar to mine but in my case there were differences in the NTLM exchange (payload was shorter than with Firefox), but they may have been a red herring. In my case this authentication started to fail after (I suppose) some server side change... "Extended Protection" may well be what was recently enabled ! I'm going to watch your issue in case it ends up solving mine too.

teake commented 1 month ago

The domain and workstations were the same for DavMail and Chrome (empty and the local hostname, respectively). There were a couple of flags set differently, but enabling / disabling those so they matched between DavMail and Chrome didn't help unfortunately.

mguessan commented 1 month ago

I think you nailed it, managed to reproduce the 401 error by enabling extended protection on IIS.

Also found Microsoft implementation of channel binding with NTLM in JDBC driver branch: https://github.com/microsoft/mssql-jdbc/commit/71f06b70618c8153dbb917c05974bba73d7095e2

Seems tricky to implement: reflection to get information from TLS layer, and additional fields in NTLM message

mguessan commented 1 month ago

Update: I discovered that HTTPClient 4 now includes an NTLM implementation with some channel binding code, however it's not active by default => will try to remove JCIFS and switch to this.

teake commented 1 month ago

The latest revision (8e76f6e2418a783a0dda930c44d43056eb4dec70) works for me. Thanks!

mguessan commented 1 month ago

Awesome, thanks for your quick feedback.

Will now be able to completely drop JCIFS as we rely on HttpClient implementation of NTLM