Sandor Farkas
Sandor Farkas

Reputation: 153

NTLM authentication fails after type 2 response

I have a site with SSO, which is using NTLM authentication, which was working perfectly so far on XP and win 7 (32bit), but recently my company decided to use win 7 (64bit) computers as well. On these PCs, the handshake ends after type 2 message, and tomcat returns 401. I have no clue how to investigate, maybe someone here can give me some tips.

This is in the servlet's doPost method:

        try {
        // NTLM Handshake
        // 1: Client --> Server | GET ...
        // 2: Client <-- Server | 401 Unauthorized/WWW-Authenticate: NTLM

        String auth = request.getHeader("Authorization");
        if (auth == null) {
            response.setStatus(response.SC_UNAUTHORIZED);
            response.setHeader("WWW-Authenticate", "NTLM");
            response.flushBuffer();
            return;
        }
        if (auth.startsWith("NTLM ")) {
            byte[] msg = new sun.misc.BASE64Decoder().decodeBuffer(auth
                    .substring(5));
            int off = 0, length, offset;

            // 3: Client --> Server | GET .../Authorization: NTLM
            // <base64-encoded type-1-message>
            if (msg[8] == 1) {
                // 4: Client <-- Server | 401 Unauthorized/WWW-Authenticate:
                // NTLM <base64-encoded type-2-message>
                byte z = 0;
                byte[] msg1 = { (byte) 'N', (byte) 'T', (byte) 'L',
                        (byte) 'M', (byte) 'S', (byte) 'S', (byte) 'P', z,
                        (byte) 2, z, z, z, z, z, z, z, (byte) 40, z, z, z,
                        (byte) 1, (byte) 130, z, z, z, (byte) 2, (byte) 2,
                        (byte) 2, z, z, z, z, z, z, z, z, z, z, z, z };

                response.setHeader("WWW-Authenticate", "NTLM "
                        + new sun.misc.BASE64Encoder().encodeBuffer(msg1));
                //response.sendError(response.SC_UNAUTHORIZED);
                response.setStatus(response.SC_UNAUTHORIZED);
                response.flushBuffer();
                return;
            }
            // 5: Client --> Server | GET .../Authorization: NTLM
            // <base64-encoded type-3-message>
            else if (msg[8] == 3) {
                off = 30;

                length = msg[off + 17] * 256 + msg[off + 16];
                offset = msg[off + 19] * 256 + msg[off + 18];
                String remoteHost = new String(msg, offset, length);

                length = msg[off + 1] * 256 + msg[off];
                offset = msg[off + 3] * 256 + msg[off + 2];
                String domain = new String(msg, offset, length);

                for (int i = 0; i < domain.length(); i += 2)
                    loginDomain += domain.charAt(i);

                length = msg[off + 9] * 256 + msg[off + 8];
                offset = msg[off + 11] * 256 + msg[off + 10];
                String username = new String(msg, offset, length);

                for (int i = 0; i < username.length(); i += 2)
                    loginUser += username.charAt(i);
            }
        }
    } catch (Exception se) {
        log.error(loginUser + ", NTLM handshake exception:", se);
    }

Upvotes: 3

Views: 7249

Answers (4)

angryMan
angryMan

Reputation: 71

Try this

Enable NTLM Extended Security using below code

byte[] msg1 = {
  (byte) 'N', (byte) 'T', (byte) 'L', (byte) 'M',
  (byte) 'S', (byte) 'S', (byte) 'P',
  z, (byte) 2, z, z, z, z, z, z, z, (byte) 40, z, z, z,
  (byte) 1, (byte) 130, **(byte) 8**, z, z, (byte) 2, (byte) 2,
  (byte) 2, z, z, z, z, z, z, z, z, z, z, z, z 
};

Upvotes: 5

Jo&#227;o Kramer
Jo&#227;o Kramer

Reputation: 15

If you still want to insist with JCIFS try these links to overcome the "Invalid parameter error" and "Failed to negotiate with a suitable domain controller for". It works with NTLM but is not guaranteed to work with NTLMv2 more secure.

"Invalid parameter" https://www.sysaid.com/Sysforums/posts/list/9065.page .

"Failed to negotiate with a suitable domain controller for" https://lists.samba.org/archive/jcifs/2005-August/005312.html

Upvotes: 1

andyczerwonka
andyczerwonka

Reputation: 4260

Most corporate network will have moved over to NTLMv2. We ran into this problem a while ago and have acquired Jespa from http://www.ioplex.com/. As long as you have a Servlet stack, it works just fine. If you're using a non-Java EE stack like Play, I'm not aware of a solution other than turning down support to NTLMv1.

Upvotes: 0

Sandor Farkas
Sandor Farkas

Reputation: 153

It was a policy issue on the 64 bit PCs as NTLMv2 was forced. Solution is to disable these setting in security policy.

• Run "secpol.msc" This should bring up a window titled "Local Security Policy"

• Security Settings > Local Policies >Security Options > "Network Security: Minimum session security for NTLM SSP based …"

There are two similar entries which begins like this, open and uncheck "Require NTLMv2 session security".

At least it turned out we are using NTLMv1. :|

Upvotes: 2

Related Questions