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