1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.proxy;
21
22 import static org.apache.mina.proxy.utils.ByteUtilities.asHex;
23
24 import java.io.PrintWriter;
25 import java.io.UnsupportedEncodingException;
26 import java.security.MessageDigest;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.Security;
29
30 import junit.framework.TestCase;
31
32 import org.apache.mina.proxy.handlers.http.ntlm.NTLMResponses;
33 import org.apache.mina.proxy.handlers.http.ntlm.NTLMUtilities;
34 import org.apache.mina.proxy.utils.ByteUtilities;
35 import org.apache.mina.proxy.utils.MD4Provider;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43
44
45
46 public class NTLMTest extends TestCase {
47 private final static Logger logger = LoggerFactory
48 .getLogger(NTLMTest.class);
49
50 static {
51 if (Security.getProvider("MINA") == null) {
52 Security.addProvider(new MD4Provider());
53 }
54 }
55
56
57
58
59 public void testEncoding() throws UnsupportedEncodingException {
60 assertEquals("d204", asHex(ByteUtilities.writeShort((short) 1234)));
61 assertEquals("d2040000", asHex(ByteUtilities.writeInt(1234)));
62 assertEquals("01000000", asHex(ByteUtilities.writeInt((short) 1)));
63 assertEquals("4e544c4d53535000", asHex(NTLMUtilities.NTLM_SIGNATURE));
64
65 assertEquals("680065006c006c006f00", asHex(ByteUtilities
66 .getUTFStringAsByteArray("hello")));
67 assertEquals("48454c4c4f", asHex(ByteUtilities
68 .getOEMStringAsByteArray("HELLO")));
69 }
70
71
72
73
74 public void testMethods() {
75 byte[] buf = new byte[4];
76 ByteUtilities.intToNetworkByteOrder(1234, buf, 0, 4);
77 assertEquals("000004d2", asHex(buf));
78 assertEquals(1234, ByteUtilities.networkByteOrderToInt(buf, 0, 4));
79 }
80
81
82
83
84 public void testSecurityBuffer() {
85 byte[] secBuf = new byte[8];
86 NTLMUtilities.writeSecurityBuffer((short) 1234, (short) 1234, 4321,
87 secBuf, 0);
88 assertEquals("d204d204e1100000", asHex(secBuf));
89 }
90
91
92
93
94 public void testType1Message() {
95 int customFlags = NTLMUtilities.FLAG_NEGOTIATE_UNICODE
96 | NTLMUtilities.FLAG_NEGOTIATE_OEM
97 | NTLMUtilities.FLAG_NEGOTIATE_NTLM
98 | NTLMUtilities.FLAG_REQUEST_SERVER_AUTH_REALM
99 | NTLMUtilities.FLAG_NEGOTIATE_DOMAIN_SUPPLIED
100 | NTLMUtilities.FLAG_NEGOTIATE_WORKSTATION_SUPPLIED;
101
102 byte[] osVer = new byte[8];
103 NTLMUtilities
104 .writeOSVersion((byte) 5, (byte) 0, (short) 2195, osVer, 0);
105
106 String msgType1 = asHex(NTLMUtilities.createType1Message("WORKSTATION",
107 "DOMAIN", customFlags, osVer));
108 assertEquals(
109 "4e544c4d53535000010000000732000006000600330000000b000b0028000000"
110 + "050093080000000f574f524b53544154494f4e444f4d41494e",
111 msgType1);
112
113 assertEquals("050093080000000f", asHex(osVer));
114
115
116 String os = System.getProperty("os.name");
117 if (os != null && os.toUpperCase().contains("WINDOWS") &&
118 "5.1".equals(System.getProperty("os.version"))) {
119 String hex = asHex(NTLMUtilities.getOsVersion());
120 assertEquals("0501", hex.substring(0, 4));
121 assertEquals(16, hex.length());
122 }
123 }
124
125
126
127
128
129 public void testType3Message() throws Exception {
130 try {
131 MessageDigest.getInstance("MD4");
132 } catch (NoSuchAlgorithmException ex) {
133 logger.warn("No MD4 digest provider found !");
134 return;
135 }
136
137 int flags = 0x00000001 | 0x00000200 | 0x00010000 | 0x00800000;
138 String msg = "4e544c4d53535000020000000c000c003000000001028100"
139 + "0123456789abcdef0000000000000000620062003c000000"
140 + "44004f004d00410049004e0002000c0044004f004d004100"
141 + "49004e0001000c0053004500520056004500520004001400"
142 + "64006f006d00610069006e002e0063006f006d0003002200"
143 + "7300650072007600650072002e0064006f006d0061006900"
144 + "6e002e0063006f006d0000000000";
145
146 byte[] challengePacket = ByteUtilities.asByteArray(msg);
147 int serverFlags = NTLMUtilities
148 .extractFlagsFromType2Message(challengePacket);
149 assertEquals(flags, serverFlags);
150
151 NTLMUtilities
152 .printTargetInformationBlockFromType2Message(challengePacket,
153 serverFlags, new PrintWriter(System.out, true));
154
155 byte[] osVer = new byte[8];
156 NTLMUtilities
157 .writeOSVersion((byte) 5, (byte) 0, (short) 2195, osVer, 0);
158
159 byte[] challenge = NTLMUtilities
160 .extractChallengeFromType2Message(challengePacket);
161 assertEquals("0123456789abcdef", asHex(challenge));
162
163 String expectedTargetInfoBlock = "02000c0044004f004d00410049004e00"
164 + "01000c00530045005200560045005200"
165 + "0400140064006f006d00610069006e00"
166 + "2e0063006f006d000300220073006500"
167 + "72007600650072002e0064006f006d00"
168 + "610069006e002e0063006f006d000000" + "0000";
169
170 byte[] targetInfo = NTLMUtilities.extractTargetInfoFromType2Message(
171 challengePacket, null);
172 assertEquals(expectedTargetInfoBlock, asHex(targetInfo));
173
174 assertEquals("DOMAIN", NTLMUtilities.extractTargetNameFromType2Message(
175 challengePacket, new Integer(serverFlags)));
176
177 serverFlags = 0x00000001 | 0x00000200;
178 String msgType3 = asHex(NTLMUtilities.createType3Message("user",
179 "SecREt01", challenge, "DOMAIN", "WORKSTATION", serverFlags,
180 null));
181
182 String expected = "4e544c4d5353500003000000180018006a00000018001800"
183 + "820000000c000c0040000000080008004c00000016001600"
184 + "54000000000000009a0000000102000044004f004d004100"
185 + "49004e00750073006500720057004f0052004b0053005400"
186 + "4100540049004f004e00c337cd5cbd44fc9782a667af6d42"
187 + "7c6de67c20c2d3e77c5625a98c1c31e81847466b29b2df46"
188 + "80f39958fb8c213a9cc6";
189 assertEquals(expected, msgType3);
190 }
191
192
193
194
195 public void testFlags() {
196 int flags = NTLMUtilities.FLAG_NEGOTIATE_UNICODE
197 | NTLMUtilities.FLAG_REQUEST_SERVER_AUTH_REALM
198 | NTLMUtilities.FLAG_NEGOTIATE_NTLM
199 | NTLMUtilities.FLAG_NEGOTIATE_ALWAYS_SIGN;
200
201 int flags2 = NTLMUtilities.FLAG_NEGOTIATE_UNICODE
202 | NTLMUtilities.FLAG_REQUEST_SERVER_AUTH_REALM
203 | NTLMUtilities.FLAG_NEGOTIATE_NTLM;
204
205 assertEquals(flags2, flags
206 & (~NTLMUtilities.FLAG_NEGOTIATE_ALWAYS_SIGN));
207 assertEquals(flags2, flags2
208 & (~NTLMUtilities.FLAG_NEGOTIATE_ALWAYS_SIGN));
209 assertEquals("05820000", asHex(ByteUtilities.writeInt(flags)));
210
211 byte[] testFlags = ByteUtilities.asByteArray("7F808182");
212 assertEquals("7f808182", asHex(testFlags));
213 ByteUtilities.changeByteEndianess(testFlags, 0, 4);
214 assertEquals("807f8281", asHex(testFlags));
215 ByteUtilities.changeByteEndianess(testFlags, 0, 4);
216 ByteUtilities.changeWordEndianess(testFlags, 0, 4);
217 assertEquals("8281807f", asHex(testFlags));
218 }
219
220
221
222
223
224 public void testResponses() throws Exception {
225 try {
226 MessageDigest.getInstance("MD4");
227 } catch (NoSuchAlgorithmException ex) {
228 logger.warn("No MD4 digest provider found !");
229 return;
230 }
231
232 String LMResponse = "c337cd5cbd44fc9782a667af6d427c6de67c20c2d3e77c56";
233
234 assertEquals(LMResponse, asHex(NTLMResponses.getLMResponse("SecREt01",
235 ByteUtilities.asByteArray("0123456789abcdef"))));
236
237 String NTLMResponse = "25a98c1c31e81847466b29b2df4680f39958fb8c213a9cc6";
238
239 assertEquals(NTLMResponse, asHex(NTLMResponses.getNTLMResponse(
240 "SecREt01", ByteUtilities.asByteArray("0123456789abcdef"))));
241
242 String LMv2Response = "d6e6152ea25d03b7c6ba6629c2d6aaf0ffffff0011223344";
243
244 assertEquals(LMv2Response, asHex(NTLMResponses.getLMv2Response(
245 "DOMAIN", "user", "SecREt01", ByteUtilities
246 .asByteArray("0123456789abcdef"), ByteUtilities
247 .asByteArray("ffffff0011223344"))));
248
249 String NTLM2Response = "10d550832d12b2ccb79d5ad1f4eed3df82aca4c3681dd455";
250
251 assertEquals(NTLM2Response, asHex(NTLMResponses
252 .getNTLM2SessionResponse("SecREt01", ByteUtilities
253 .asByteArray("0123456789abcdef"), ByteUtilities
254 .asByteArray("ffffff0011223344"))));
255
256 String NTLMv2Response = "cbabbca713eb795d04c97abc01ee4983"
257 + "01010000000000000090d336b734c301"
258 + "ffffff00112233440000000002000c00"
259 + "44004f004d00410049004e0001000c00"
260 + "53004500520056004500520004001400"
261 + "64006f006d00610069006e002e006300"
262 + "6f006d00030022007300650072007600"
263 + "650072002e0064006f006d0061006900"
264 + "6e002e0063006f006d00000000000000" + "0000";
265
266 String targetInformation = "02000c0044004f004d00410049004e00"
267 + "01000c00530045005200560045005200"
268 + "0400140064006f006d00610069006e00"
269 + "2e0063006f006d000300220073006500"
270 + "72007600650072002e0064006f006d00"
271 + "610069006e002e0063006f006d000000" + "0000";
272
273 assertEquals(NTLMv2Response, asHex(NTLMResponses.getNTLMv2Response(
274 "DOMAIN", "user", "SecREt01", ByteUtilities
275 .asByteArray(targetInformation), ByteUtilities
276 .asByteArray("0123456789abcdef"), ByteUtilities
277 .asByteArray("ffffff0011223344"), 1055844000000L)));
278 }
279 }