/** * Process a type 1 NTLM message * * @param type1Msg Type1NTLMMessage * @param req HttpServletRequest * @param res HttpServletResponse * @exception IOException */ protected void processType1( Type1NTLMMessage type1Msg, HttpServletRequest req, HttpServletResponse res) throws IOException { if (getLogger().isDebugEnabled()) getLogger().debug("Received type1 " + type1Msg); // Get the existing NTLM details NTLMLogonDetails ntlmDetails = null; HttpSession session = req.getSession(); ntlmDetails = (NTLMLogonDetails) session.getAttribute(NTLM_AUTH_DETAILS); // Check if cached logon details are available if (ntlmDetails != null && ntlmDetails.hasType2Message() && ntlmDetails.hasNTLMHashedPassword() && ntlmDetails.hasAuthenticationToken()) { // Get the authentication server type2 response Type2NTLMMessage cachedType2 = ntlmDetails.getType2Message(); byte[] type2Bytes = cachedType2.getBytes(); String ntlmBlob = "NTLM " + new String(Base64.encodeBase64(type2Bytes)); if (getLogger().isDebugEnabled()) getLogger().debug("Sending cached NTLM type2 to client - " + cachedType2); // Send back a request for NTLM authentication res.setHeader(WWW_AUTHENTICATE, ntlmBlob); res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); res.flushBuffer(); } else { // Clear any cached logon details session.removeAttribute(NTLM_AUTH_DETAILS); // Set the 8 byte challenge for the new logon request byte[] challenge = null; NTLMPassthruToken authToken = null; if (nltmAuthenticator.getNTLMMode() == NTLMMode.MD4_PROVIDER) { // Generate a random 8 byte challenge challenge = new byte[8]; DataPacker.putIntelLong(m_random.nextLong(), challenge, 0); } else { // Get the client domain String domain = type1Msg.getDomain(); if (domain == null || domain.length() == 0) { domain = mapClientAddressToDomain(req.getRemoteAddr()); } if (getLogger().isDebugEnabled()) getLogger().debug("Client domain " + domain); // Create an authentication token for the new logon authToken = new NTLMPassthruToken(domain); // Run the first stage of the passthru authentication to get the challenge nltmAuthenticator.authenticate(authToken); // Get the challenge from the token if (authToken.getChallenge() != null) { challenge = authToken.getChallenge().getBytes(); } } // Get the flags from the client request and mask out unsupported features int ntlmFlags = type1Msg.getFlags() & m_ntlmFlags; // Build a type2 message to send back to the client, containing the challenge List<TargetInfo> tList = new ArrayList<TargetInfo>(); String srvName = getServerName(); tList.add(new TargetInfo(NTLM.TargetServer, srvName)); Type2NTLMMessage type2Msg = new Type2NTLMMessage(); type2Msg.buildType2(ntlmFlags, srvName, challenge, null, tList); // Store the NTLM logon details, cache the type2 message, and token if using passthru ntlmDetails = new NTLMLogonDetails(); ntlmDetails.setType2Message(type2Msg); ntlmDetails.setAuthenticationToken(authToken); session.setAttribute(NTLM_AUTH_DETAILS, ntlmDetails); if (getLogger().isDebugEnabled()) getLogger().debug("Sending NTLM type2 to client - " + type2Msg); // Send back a request for NTLM authentication byte[] type2Bytes = type2Msg.getBytes(); String ntlmBlob = "NTLM " + new String(Base64.encodeBase64(type2Bytes)); res.setHeader(WWW_AUTHENTICATE, ntlmBlob); res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); res.flushBuffer(); } }