CVE-2018-1139 libcli/auth: Add initial tests for ntlm_password_check()
[Samba.git] / libcli / auth / tests / ntlm_check.c
blobe87a0a276d4934db709dd73a8b3c8a112414ee48
1 /*
2 * Unit tests for the ntlm_check password hash check library.
4 * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * from cmocka.c:
23 * These headers or their equivalents should be included prior to
24 * including
25 * this header file.
27 * #include <stdarg.h>
28 * #include <stddef.h>
29 * #include <setjmp.h>
31 * This allows test applications to use custom definitions of C standard
32 * library functions and types.
37 * Note that the messaging routines (audit_message_send and get_event_server)
38 * are not tested by these unit tests. Currently they are for integration
39 * test support, and as such are exercised by the integration tests.
41 #include <stdarg.h>
42 #include <stddef.h>
43 #include <setjmp.h>
44 #include <cmocka.h>
46 #include "includes.h"
47 #include "../lib/crypto/crypto.h"
48 #include "librpc/gen_ndr/netlogon.h"
49 #include "libcli/auth/libcli_auth.h"
50 #include "auth/credentials/credentials.h"
52 struct ntlm_state {
53 const char *username;
54 const char *domain;
55 DATA_BLOB challenge;
56 DATA_BLOB ntlm;
57 DATA_BLOB lm;
58 DATA_BLOB ntlm_key;
59 DATA_BLOB lm_key;
60 const struct samr_Password *nt_hash;
63 static int test_ntlm_setup_with_options(void **state,
64 int flags, bool upn)
66 NTSTATUS status;
67 DATA_BLOB challenge = {
68 .data = discard_const_p(uint8_t, "I am a teapot"),
69 .length = 8
71 struct ntlm_state *ntlm_state = talloc(NULL, struct ntlm_state);
72 DATA_BLOB target_info = NTLMv2_generate_names_blob(ntlm_state,
73 NULL,
74 "serverdom");
75 struct cli_credentials *creds = cli_credentials_init(ntlm_state);
76 cli_credentials_set_username(creds,
77 "testuser",
78 CRED_SPECIFIED);
79 cli_credentials_set_domain(creds,
80 "testdom",
81 CRED_SPECIFIED);
82 cli_credentials_set_workstation(creds,
83 "testwksta",
84 CRED_SPECIFIED);
85 cli_credentials_set_password(creds,
86 "testpass",
87 CRED_SPECIFIED);
89 if (upn) {
90 cli_credentials_set_principal(creds,
91 "testuser@samba.org",
92 CRED_SPECIFIED);
95 cli_credentials_get_ntlm_username_domain(creds,
96 ntlm_state,
97 &ntlm_state->username,
98 &ntlm_state->domain);
100 status = cli_credentials_get_ntlm_response(creds,
101 ntlm_state,
102 &flags,
103 challenge,
104 NULL,
105 target_info,
106 &ntlm_state->lm,
107 &ntlm_state->ntlm,
108 &ntlm_state->lm_key,
109 &ntlm_state->ntlm_key);
110 ntlm_state->challenge = challenge;
112 ntlm_state->nt_hash = cli_credentials_get_nt_hash(creds,
113 ntlm_state);
115 if (!NT_STATUS_IS_OK(status)) {
116 return -1;
119 *state = ntlm_state;
120 return 0;
123 static int test_ntlm_setup(void **state) {
124 return test_ntlm_setup_with_options(state, 0, false);
127 static int test_ntlm_and_lm_setup(void **state) {
128 return test_ntlm_setup_with_options(state,
129 CLI_CRED_LANMAN_AUTH,
130 false);
133 static int test_ntlm2_setup(void **state) {
134 return test_ntlm_setup_with_options(state,
135 CLI_CRED_NTLM2,
136 false);
139 static int test_ntlmv2_setup(void **state) {
140 return test_ntlm_setup_with_options(state,
141 CLI_CRED_NTLMv2_AUTH,
142 false);
145 static int test_ntlm_teardown(void **state)
147 struct ntlm_state *ntlm_state
148 = talloc_get_type_abort(*state,
149 struct ntlm_state);
150 TALLOC_FREE(ntlm_state);
151 *state = NULL;
152 return 0;
155 static void test_ntlm_allowed(void **state)
157 DATA_BLOB user_sess_key, lm_sess_key;
158 struct ntlm_state *ntlm_state
159 = talloc_get_type_abort(*state,
160 struct ntlm_state);
161 NTSTATUS status;
162 status = ntlm_password_check(ntlm_state,
163 false,
164 NTLM_AUTH_ON,
166 &ntlm_state->challenge,
167 &ntlm_state->lm,
168 &ntlm_state->ntlm,
169 ntlm_state->username,
170 ntlm_state->username,
171 ntlm_state->domain,
172 NULL,
173 ntlm_state->nt_hash,
174 &user_sess_key,
175 &lm_sess_key);
177 assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
180 static void test_ntlm_allowed_lm_supplied(void **state)
182 return test_ntlm_allowed(state);
185 static void test_ntlm_disabled(void **state)
187 DATA_BLOB user_sess_key, lm_sess_key;
188 struct ntlm_state *ntlm_state
189 = talloc_get_type_abort(*state,
190 struct ntlm_state);
191 NTSTATUS status;
192 status = ntlm_password_check(ntlm_state,
193 false,
194 NTLM_AUTH_DISABLED,
196 &ntlm_state->challenge,
197 &ntlm_state->lm,
198 &ntlm_state->ntlm,
199 ntlm_state->username,
200 ntlm_state->username,
201 ntlm_state->domain,
202 NULL,
203 ntlm_state->nt_hash,
204 &user_sess_key,
205 &lm_sess_key);
207 assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_NTLM_BLOCKED));
210 static void test_ntlm2(void **state)
212 DATA_BLOB user_sess_key, lm_sess_key;
213 struct ntlm_state *ntlm_state
214 = talloc_get_type_abort(*state,
215 struct ntlm_state);
216 NTSTATUS status;
217 status = ntlm_password_check(ntlm_state,
218 false,
219 NTLM_AUTH_ON,
221 &ntlm_state->challenge,
222 &ntlm_state->lm,
223 &ntlm_state->ntlm,
224 ntlm_state->username,
225 ntlm_state->username,
226 ntlm_state->domain,
227 NULL,
228 ntlm_state->nt_hash,
229 &user_sess_key,
230 &lm_sess_key);
233 * NTLM2 session security (where the real challenge is the
234 * MD5(challenge, client-challenge) (in the first 8 bytes of
235 * the lm) isn't decoded by ntlm_password_check(), it must
236 * first be converted back into normal NTLM by the NTLMSSP
237 * layer
239 assert_int_equal(NT_STATUS_V(status),
240 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
243 static void test_ntlm_mschapv2_only_allowed(void **state)
245 DATA_BLOB user_sess_key, lm_sess_key;
246 struct ntlm_state *ntlm_state
247 = talloc_get_type_abort(*state,
248 struct ntlm_state);
249 NTSTATUS status;
250 status = ntlm_password_check(ntlm_state,
251 false,
252 NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY,
253 MSV1_0_ALLOW_MSVCHAPV2,
254 &ntlm_state->challenge,
255 &ntlm_state->lm,
256 &ntlm_state->ntlm,
257 ntlm_state->username,
258 ntlm_state->username,
259 ntlm_state->domain,
260 NULL,
261 ntlm_state->nt_hash,
262 &user_sess_key,
263 &lm_sess_key);
265 assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
268 static void test_ntlm_mschapv2_only_denied(void **state)
270 DATA_BLOB user_sess_key, lm_sess_key;
271 struct ntlm_state *ntlm_state
272 = talloc_get_type_abort(*state,
273 struct ntlm_state);
274 NTSTATUS status;
275 status = ntlm_password_check(ntlm_state,
276 false,
277 NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY,
279 &ntlm_state->challenge,
280 &ntlm_state->lm,
281 &ntlm_state->ntlm,
282 ntlm_state->username,
283 ntlm_state->username,
284 ntlm_state->domain,
285 NULL,
286 ntlm_state->nt_hash,
287 &user_sess_key,
288 &lm_sess_key);
290 assert_int_equal(NT_STATUS_V(status),
291 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
294 static void test_ntlmv2_only_ntlmv2(void **state)
296 DATA_BLOB user_sess_key, lm_sess_key;
297 struct ntlm_state *ntlm_state
298 = talloc_get_type_abort(*state,
299 struct ntlm_state);
300 NTSTATUS status;
301 status = ntlm_password_check(ntlm_state,
302 false,
303 NTLM_AUTH_NTLMV2_ONLY,
305 &ntlm_state->challenge,
306 &ntlm_state->lm,
307 &ntlm_state->ntlm,
308 ntlm_state->username,
309 ntlm_state->username,
310 ntlm_state->domain,
311 NULL,
312 ntlm_state->nt_hash,
313 &user_sess_key,
314 &lm_sess_key);
316 assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
319 static void test_ntlmv2_only_ntlm(void **state)
321 DATA_BLOB user_sess_key, lm_sess_key;
322 struct ntlm_state *ntlm_state
323 = talloc_get_type_abort(*state,
324 struct ntlm_state);
325 NTSTATUS status;
326 status = ntlm_password_check(ntlm_state,
327 false,
328 NTLM_AUTH_NTLMV2_ONLY,
330 &ntlm_state->challenge,
331 &ntlm_state->lm,
332 &ntlm_state->ntlm,
333 ntlm_state->username,
334 ntlm_state->username,
335 ntlm_state->domain,
336 NULL,
337 ntlm_state->nt_hash,
338 &user_sess_key,
339 &lm_sess_key);
341 assert_int_equal(NT_STATUS_V(status),
342 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
345 static void test_ntlmv2_only_ntlm_and_lanman(void **state)
347 return test_ntlmv2_only_ntlm(state);
350 static void test_ntlmv2_only_ntlm_once(void **state)
352 DATA_BLOB user_sess_key, lm_sess_key;
353 struct ntlm_state *ntlm_state
354 = talloc_get_type_abort(*state,
355 struct ntlm_state);
356 NTSTATUS status;
357 status = ntlm_password_check(ntlm_state,
358 false,
359 NTLM_AUTH_NTLMV2_ONLY,
361 &ntlm_state->challenge,
362 &data_blob_null,
363 &ntlm_state->ntlm,
364 ntlm_state->username,
365 ntlm_state->username,
366 ntlm_state->domain,
367 NULL,
368 ntlm_state->nt_hash,
369 &user_sess_key,
370 &lm_sess_key);
372 assert_int_equal(NT_STATUS_V(status),
373 NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
376 int main(int argc, const char **argv)
378 const struct CMUnitTest tests[] = {
379 cmocka_unit_test_setup_teardown(test_ntlm_allowed,
380 test_ntlm_setup,
381 test_ntlm_teardown),
382 cmocka_unit_test_setup_teardown(test_ntlm_allowed_lm_supplied,
383 test_ntlm_and_lm_setup,
384 test_ntlm_teardown),
385 cmocka_unit_test_setup_teardown(test_ntlm_disabled,
386 test_ntlm_setup,
387 test_ntlm_teardown),
388 cmocka_unit_test_setup_teardown(test_ntlm2,
389 test_ntlm2_setup,
390 test_ntlm_teardown),
391 cmocka_unit_test_setup_teardown(test_ntlm_mschapv2_only_allowed,
392 test_ntlm_setup,
393 test_ntlm_teardown),
394 cmocka_unit_test_setup_teardown(test_ntlm_mschapv2_only_denied,
395 test_ntlm_setup,
396 test_ntlm_teardown),
397 cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlm,
398 test_ntlm_setup,
399 test_ntlm_teardown),
400 cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlm_and_lanman,
401 test_ntlm_and_lm_setup,
402 test_ntlm_teardown),
403 cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlm_once,
404 test_ntlm_setup,
405 test_ntlm_teardown),
406 cmocka_unit_test_setup_teardown(test_ntlmv2_only_ntlmv2,
407 test_ntlmv2_setup,
408 test_ntlm_teardown)
411 cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
412 return cmocka_run_group_tests(tests, NULL, NULL);