/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.security.sso.ntlm.internal; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.StringPool; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import jcifs.ntlmssp.NtlmFlags; import jcifs.ntlmssp.Type1Message; import jcifs.ntlmssp.Type2Message; import jcifs.ntlmssp.Type3Message; import jcifs.util.Encdec; /** * @author Marcellus Tavares * @author Michael C. Han */ public class NtlmManager { public NtlmManager( NetlogonConnectionManager netlogonConnectionManager, String domain, String domainController, String domainControllerName, String serviceAccount, String servicePassword) { _netlogonConnectionManager = netlogonConnectionManager; setConfiguration( domain, domainController, domainControllerName, serviceAccount, servicePassword); } public NtlmUserAccount authenticate(byte[] material, byte[] serverChallenge) throws IOException, NoSuchAlgorithmException, NtlmLogonException { Type3Message type3Message = new Type3Message(material); if (type3Message.getFlag( _NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY) && (type3Message.getNTResponse().length == 24)) { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); byte[] bytes = new byte[16]; System.arraycopy(serverChallenge, 0, bytes, 0, 8); System.arraycopy(type3Message.getLMResponse(), 0, bytes, 8, 8); messageDigest.update(bytes); serverChallenge = messageDigest.digest(); } return _netlogon.logon( type3Message.getDomain(), type3Message.getUser(), type3Message.getWorkstation(), serverChallenge, type3Message.getNTResponse(), type3Message.getLMResponse()); } public String getDomain() { return _domain; } public String getDomainController() { return _domainController; } public String getDomainControllerName() { return _domainControllerName; } public String getServiceAccount() { return _ntlmServiceAccount.getAccount(); } public String getServicePassword() { return _ntlmServiceAccount.getPassword(); } public byte[] negotiate(byte[] material, byte[] serverChallenge) throws IOException { Type1Message type1Message = new Type1Message(material); Type2Message type2Message = new Type2Message( type1Message.getFlags(), serverChallenge, _domain); if (type2Message.getFlag( _NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY)) { type2Message.setFlag(NtlmFlags.NTLMSSP_NEGOTIATE_LM_KEY, false); type2Message.setFlag(NtlmFlags.NTLMSSP_NEGOTIATE_TARGET_INFO, true); type2Message.setTargetInformation(getTargetInformation()); } return type2Message.toByteArray(); } public void setConfiguration( String domain, String domainController, String domainControllerName, String serviceAccount, String servicePassword) { _domain = domain; _domainController = domainController; _domainControllerName = domainControllerName; _ntlmServiceAccount = new NtlmServiceAccount( serviceAccount, servicePassword); _netlogon = new Netlogon( domainController, domainControllerName, _netlogonConnectionManager, _ntlmServiceAccount); } protected byte[] getAVPairBytes(int avId, String value) throws UnsupportedEncodingException { byte[] valueBytes = value.getBytes("UTF-16LE"); byte[] avPairBytes = new byte[4 + valueBytes.length]; Encdec.enc_uint16le((short)avId, avPairBytes, 0); Encdec.enc_uint16le((short)valueBytes.length, avPairBytes, 2); System.arraycopy(valueBytes, 0, avPairBytes, 4, valueBytes.length); return avPairBytes; } protected byte[] getTargetInformation() throws UnsupportedEncodingException { byte[] computerName = getAVPairBytes( 1, _ntlmServiceAccount.getComputerName()); byte[] domainName = getAVPairBytes(2, _domain); byte[] targetInformation = ArrayUtil.append(computerName, domainName); byte[] eol = getAVPairBytes(0, StringPool.BLANK); targetInformation = ArrayUtil.append(targetInformation, eol); return targetInformation; } private static final int _NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY = 0x00080000; private String _domain; private String _domainController; private String _domainControllerName; private Netlogon _netlogon; private final NetlogonConnectionManager _netlogonConnectionManager; private NtlmServiceAccount _ntlmServiceAccount; }