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