LCOV - code coverage report
Current view: top level - libcli/auth/tests - ntlm_check.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 129 130 99.2 %
Date: 2024-04-21 15:09:00 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Unit tests for the ntlm_check password hash check library.
       3             :  *
       4             :  *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2018
       5             :  *
       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.
      10             :  *
      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.
      15             :  *
      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/>.
      18             :  *
      19             :  */
      20             : 
      21             : /*
      22             :  * from cmocka.c:
      23             :  * These headers or their equivalents should be included prior to
      24             :  * including
      25             :  * this header file.
      26             :  *
      27             :  * #include <stdarg.h>
      28             :  * #include <stddef.h>
      29             :  * #include <setjmp.h>
      30             :  *
      31             :  * This allows test applications to use custom definitions of C standard
      32             :  * library functions and types.
      33             :  *
      34             :  */
      35             : 
      36             : /*
      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.
      40             :  */
      41             : #include <stdarg.h>
      42             : #include <stddef.h>
      43             : #include <stdint.h>
      44             : #include <setjmp.h>
      45             : #include <cmocka.h>
      46             : 
      47             : #include "includes.h"
      48             : #include "librpc/gen_ndr/netlogon.h"
      49             : #include "libcli/auth/libcli_auth.h"
      50             : #include "auth/credentials/credentials.h"
      51             : 
      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;
      61             : };
      62             : 
      63          10 : static int test_ntlm_setup_with_options(void **state,
      64             :                                         int flags, bool upn)
      65             : {
      66          10 :         NTSTATUS status;
      67          10 :         DATA_BLOB challenge = {
      68             :                 .data = discard_const_p(uint8_t, "I am a teapot"),
      69             :                 .length = 8
      70             :         };
      71          10 :         struct ntlm_state *ntlm_state = talloc(NULL, struct ntlm_state);
      72          10 :         DATA_BLOB target_info = NTLMv2_generate_names_blob(ntlm_state,
      73             :                                                            NULL,
      74             :                                                            "serverdom");
      75          10 :         struct cli_credentials *creds = cli_credentials_init(ntlm_state);
      76          10 :         cli_credentials_set_username(creds,
      77             :                                      "testuser",
      78             :                                      CRED_SPECIFIED);
      79          10 :         cli_credentials_set_domain(creds,
      80             :                                    "testdom",
      81             :                                    CRED_SPECIFIED);
      82          10 :         cli_credentials_set_workstation(creds,
      83             :                                         "testwksta",
      84             :                                         CRED_SPECIFIED);
      85          10 :         cli_credentials_set_password(creds,
      86             :                                      "testpass",
      87             :                                      CRED_SPECIFIED);
      88             : 
      89          10 :         if (upn) {
      90           0 :                 cli_credentials_set_principal(creds,
      91             :                                               "testuser@samba.org",
      92             :                                               CRED_SPECIFIED);
      93             :         }
      94             : 
      95          10 :         cli_credentials_get_ntlm_username_domain(creds,
      96             :                                                  ntlm_state,
      97             :                                                  &ntlm_state->username,
      98             :                                                  &ntlm_state->domain);
      99             : 
     100          10 :         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          10 :         ntlm_state->challenge = challenge;
     111             : 
     112          10 :         ntlm_state->nt_hash = cli_credentials_get_nt_hash(creds,
     113             :                                                           ntlm_state);
     114             : 
     115          10 :         if (!NT_STATUS_IS_OK(status)) {
     116             :                 return -1;
     117             :         }
     118             : 
     119          10 :         *state = ntlm_state;
     120          10 :         return 0;
     121             : }
     122             : 
     123           6 : static int test_ntlm_setup(void **state) {
     124           6 :         return test_ntlm_setup_with_options(state, 0, false);
     125             : }
     126             : 
     127           2 : static int test_ntlm_and_lm_setup(void **state) {
     128           2 :         return test_ntlm_setup_with_options(state,
     129             :                                             CLI_CRED_LANMAN_AUTH,
     130             :                                             false);
     131             : }
     132             : 
     133           1 : static int test_ntlm2_setup(void **state) {
     134           1 :         return test_ntlm_setup_with_options(state,
     135             :                                             CLI_CRED_NTLM2,
     136             :                                             false);
     137             : }
     138             : 
     139           1 : static int test_ntlmv2_setup(void **state) {
     140           1 :         return test_ntlm_setup_with_options(state,
     141             :                                             CLI_CRED_NTLMv2_AUTH,
     142             :                                             false);
     143             : }
     144             : 
     145          10 : static int test_ntlm_teardown(void **state)
     146             : {
     147          10 :         struct ntlm_state *ntlm_state
     148          10 :                 = talloc_get_type_abort(*state,
     149             :                                         struct ntlm_state);
     150          10 :         TALLOC_FREE(ntlm_state);
     151          10 :         *state = NULL;
     152          10 :         return 0;
     153             : }
     154             : 
     155           2 : static void test_ntlm_allowed(void **state)
     156             : {
     157           2 :         DATA_BLOB user_sess_key, lm_sess_key;
     158           2 :         struct ntlm_state *ntlm_state
     159           2 :                 = talloc_get_type_abort(*state,
     160             :                                         struct ntlm_state);
     161           2 :         NTSTATUS status;
     162           2 :         status = ntlm_password_check(ntlm_state,
     163             :                                      false,
     164             :                                      NTLM_AUTH_ON,
     165             :                                      0,
     166           2 :                                      &ntlm_state->challenge,
     167           2 :                                      &ntlm_state->lm,
     168           2 :                                      &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);
     176             : 
     177           2 :         assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
     178           2 : }
     179             : 
     180           1 : static void test_ntlm_allowed_lm_supplied(void **state)
     181             : {
     182           1 :         test_ntlm_allowed(state);
     183           1 : }
     184             : 
     185           1 : static void test_ntlm_disabled(void **state)
     186             : {
     187           1 :         DATA_BLOB user_sess_key, lm_sess_key;
     188           1 :         struct ntlm_state *ntlm_state
     189           1 :                 = talloc_get_type_abort(*state,
     190             :                                         struct ntlm_state);
     191           1 :         NTSTATUS status;
     192           1 :         status = ntlm_password_check(ntlm_state,
     193             :                                      false,
     194             :                                      NTLM_AUTH_DISABLED,
     195             :                                      0,
     196           1 :                                      &ntlm_state->challenge,
     197           1 :                                      &ntlm_state->lm,
     198           1 :                                      &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);
     206             : 
     207           1 :         assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_NTLM_BLOCKED));
     208           1 : }
     209             : 
     210           1 : static void test_ntlm2(void **state)
     211             : {
     212           1 :         DATA_BLOB user_sess_key, lm_sess_key;
     213           1 :         struct ntlm_state *ntlm_state
     214           1 :                 = talloc_get_type_abort(*state,
     215             :                                         struct ntlm_state);
     216           1 :         NTSTATUS status;
     217           1 :         status = ntlm_password_check(ntlm_state,
     218             :                                      false,
     219             :                                      NTLM_AUTH_ON,
     220             :                                      0,
     221           1 :                                      &ntlm_state->challenge,
     222           1 :                                      &ntlm_state->lm,
     223           1 :                                      &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);
     231             : 
     232             :         /*
     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
     238             :          */
     239           1 :         assert_int_equal(NT_STATUS_V(status),
     240             :                          NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
     241           1 : }
     242             : 
     243           1 : static void test_ntlm_mschapv2_only_allowed(void **state)
     244             : {
     245           1 :         DATA_BLOB user_sess_key, lm_sess_key;
     246           1 :         struct ntlm_state *ntlm_state
     247           1 :                 = talloc_get_type_abort(*state,
     248             :                                         struct ntlm_state);
     249           1 :         NTSTATUS status;
     250           1 :         status = ntlm_password_check(ntlm_state,
     251             :                                      false,
     252             :                                      NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY,
     253             :                                      MSV1_0_ALLOW_MSVCHAPV2,
     254           1 :                                      &ntlm_state->challenge,
     255           1 :                                      &ntlm_state->lm,
     256           1 :                                      &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);
     264             : 
     265           1 :         assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
     266           1 : }
     267             : 
     268           1 : static void test_ntlm_mschapv2_only_denied(void **state)
     269             : {
     270           1 :         DATA_BLOB user_sess_key, lm_sess_key;
     271           1 :         struct ntlm_state *ntlm_state
     272           1 :                 = talloc_get_type_abort(*state,
     273             :                                         struct ntlm_state);
     274           1 :         NTSTATUS status;
     275           1 :         status = ntlm_password_check(ntlm_state,
     276             :                                      false,
     277             :                                      NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY,
     278             :                                      0,
     279           1 :                                      &ntlm_state->challenge,
     280           1 :                                      &ntlm_state->lm,
     281           1 :                                      &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);
     289             : 
     290           1 :         assert_int_equal(NT_STATUS_V(status),
     291             :                          NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
     292           1 : }
     293             : 
     294           1 : static void test_ntlmv2_only_ntlmv2(void **state)
     295             : {
     296           1 :         DATA_BLOB user_sess_key, lm_sess_key;
     297           1 :         struct ntlm_state *ntlm_state
     298           1 :                 = talloc_get_type_abort(*state,
     299             :                                         struct ntlm_state);
     300           1 :         NTSTATUS status;
     301           1 :         status = ntlm_password_check(ntlm_state,
     302             :                                      false,
     303             :                                      NTLM_AUTH_NTLMV2_ONLY,
     304             :                                      0,
     305           1 :                                      &ntlm_state->challenge,
     306           1 :                                      &ntlm_state->lm,
     307           1 :                                      &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);
     315             : 
     316           1 :         assert_int_equal(NT_STATUS_V(status), NT_STATUS_V(NT_STATUS_OK));
     317           1 : }
     318             : 
     319           2 : static void test_ntlmv2_only_ntlm(void **state)
     320             : {
     321           2 :         DATA_BLOB user_sess_key, lm_sess_key;
     322           2 :         struct ntlm_state *ntlm_state
     323           2 :                 = talloc_get_type_abort(*state,
     324             :                                         struct ntlm_state);
     325           2 :         NTSTATUS status;
     326           2 :         status = ntlm_password_check(ntlm_state,
     327             :                                      false,
     328             :                                      NTLM_AUTH_NTLMV2_ONLY,
     329             :                                      0,
     330           2 :                                      &ntlm_state->challenge,
     331           2 :                                      &ntlm_state->lm,
     332           2 :                                      &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);
     340             : 
     341           2 :         assert_int_equal(NT_STATUS_V(status),
     342             :                          NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
     343           2 : }
     344             : 
     345           1 : static void test_ntlmv2_only_ntlm_and_lanman(void **state)
     346             : {
     347           1 :         test_ntlmv2_only_ntlm(state);
     348           1 : }
     349             : 
     350           1 : static void test_ntlmv2_only_ntlm_once(void **state)
     351             : {
     352           1 :         DATA_BLOB user_sess_key, lm_sess_key;
     353           1 :         struct ntlm_state *ntlm_state
     354           1 :                 = talloc_get_type_abort(*state,
     355             :                                         struct ntlm_state);
     356           1 :         NTSTATUS status;
     357           1 :         status = ntlm_password_check(ntlm_state,
     358             :                                      false,
     359             :                                      NTLM_AUTH_NTLMV2_ONLY,
     360             :                                      0,
     361           1 :                                      &ntlm_state->challenge,
     362             :                                      &data_blob_null,
     363           1 :                                      &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);
     371             : 
     372           1 :         assert_int_equal(NT_STATUS_V(status),
     373             :                          NT_STATUS_V(NT_STATUS_WRONG_PASSWORD));
     374           1 : }
     375             : 
     376           1 : int main(int argc, const char **argv)
     377             : {
     378           1 :         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)
     409             :         };
     410             : 
     411           1 :         cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
     412           1 :         return cmocka_run_group_tests(tests, NULL, NULL);
     413             : }

Generated by: LCOV version 1.14