001
014
015 package com.liferay.portal.security.ntlm;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018 import com.liferay.portal.kernel.util.StringPool;
019
020 import java.io.IOException;
021 import java.io.UnsupportedEncodingException;
022
023 import java.security.MessageDigest;
024 import java.security.NoSuchAlgorithmException;
025
026 import jcifs.ntlmssp.NtlmFlags;
027 import jcifs.ntlmssp.Type1Message;
028 import jcifs.ntlmssp.Type2Message;
029 import jcifs.ntlmssp.Type3Message;
030
031 import jcifs.util.Encdec;
032
033
037 public class NtlmManager {
038
039 public NtlmManager(
040 String domain, String domainController, String domainControllerName,
041 String serviceAccount, String servicePassword) {
042
043 setConfiguration(
044 domain, domainController, domainControllerName, serviceAccount,
045 servicePassword);
046 }
047
048 public NtlmUserAccount authenticate(byte[] material, byte[] serverChallenge)
049 throws IOException, NoSuchAlgorithmException, NtlmLogonException {
050
051 Type3Message type3Message = new Type3Message(material);
052
053 if (type3Message.getFlag(
054 _NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY) &&
055 (type3Message.getNTResponse().length == 24)) {
056
057 MessageDigest messageDigest = MessageDigest.getInstance("MD5");
058
059 byte[] bytes = new byte[16];
060
061 System.arraycopy(serverChallenge, 0, bytes, 0, 8);
062 System.arraycopy(type3Message.getLMResponse(), 0, bytes, 8, 8);
063
064 messageDigest.update(bytes);
065
066 serverChallenge = messageDigest.digest();
067 }
068
069 return _netlogon.logon(
070 type3Message.getDomain(), type3Message.getUser(),
071 type3Message.getWorkstation(), serverChallenge,
072 type3Message.getNTResponse(), type3Message.getLMResponse());
073 }
074
075 public String getDomain() {
076 return _domain;
077 }
078
079 public String getDomainController() {
080 return _domainController;
081 }
082
083 public String getDomainControllerName() {
084 return _domainControllerName;
085 }
086
087 public String getServiceAccount() {
088 return _ntlmServiceAccount.getAccount();
089 }
090
091 public String getServicePassword() {
092 return _ntlmServiceAccount.getPassword();
093 }
094
095 public byte[] negotiate(byte[] material, byte[] serverChallenge)
096 throws IOException {
097
098 Type1Message type1Message = new Type1Message(material);
099
100 Type2Message type2Message = new Type2Message(
101 type1Message.getFlags(), serverChallenge, _domain);
102
103 if (type2Message.getFlag(
104 _NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY)) {
105
106 type2Message.setFlag(NtlmFlags.NTLMSSP_NEGOTIATE_LM_KEY, false);
107 type2Message.setFlag(NtlmFlags.NTLMSSP_NEGOTIATE_TARGET_INFO, true);
108 type2Message.setTargetInformation(getTargetInformation());
109 }
110
111 return type2Message.toByteArray();
112 }
113
114 public void setConfiguration(
115 String domain, String domainController, String domainControllerName,
116 String serviceAccount, String servicePassword) {
117
118 _domain = domain;
119 _domainController = domainController;
120 _domainControllerName = domainControllerName;
121 _ntlmServiceAccount = new NtlmServiceAccount(
122 serviceAccount, servicePassword);
123
124 _netlogon = new Netlogon();
125
126 _netlogon.setConfiguration(
127 domainController, domainControllerName, _ntlmServiceAccount);
128 }
129
130 protected byte[] getAVPairBytes(int avId, String value)
131 throws UnsupportedEncodingException {
132
133 byte[] valueBytes = value.getBytes("UTF-16LE");
134 byte[] avPairBytes = new byte[4 + valueBytes.length];
135
136 Encdec.enc_uint16le((short)avId, avPairBytes, 0);
137 Encdec.enc_uint16le((short)valueBytes.length, avPairBytes, 2);
138
139 System.arraycopy(valueBytes, 0, avPairBytes, 4, valueBytes.length);
140
141 return avPairBytes;
142 }
143
144 protected byte[] getTargetInformation()
145 throws UnsupportedEncodingException {
146
147 byte[] computerName = getAVPairBytes(
148 1, _ntlmServiceAccount.getComputerName());
149 byte[] domainName = getAVPairBytes(2, _domain);
150
151 byte[] targetInformation = ArrayUtil.append(computerName, domainName);
152
153 byte[] eol = getAVPairBytes(0, StringPool.BLANK);
154
155 targetInformation = ArrayUtil.append(targetInformation, eol);
156
157 return targetInformation;
158 }
159
160 private static final int _NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY =
161 0x00080000;
162
163 private String _domain;
164 private String _domainController;
165 private String _domainControllerName;
166 private Netlogon _netlogon;
167 private NtlmServiceAccount _ntlmServiceAccount;
168
169 }