LCOV - code coverage report
Current view: top level - source4/torture/rpc - netlogon_crypto.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 8 99 8.1 %
Date: 2024-04-21 15:09:00 Functions: 1 5 20.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test suite for netlogon rpc operations
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
       8             :    Copyright (C) Tim Potter      2003
       9             :    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "lib/replace/system/network.h"
      27             : #include "lib/cmdline/cmdline.h"
      28             : #include "torture/rpc/torture_rpc.h"
      29             : #include "libcli/auth/libcli_auth.h"
      30             : #include "librpc/gen_ndr/ndr_netlogon_c.h"
      31             : #include "param/param.h"
      32             : #include "lib/param/loadparm.h"
      33             : #include "libcli/security/security.h"
      34             : 
      35             : #undef strcasecmp
      36             : 
      37             : #define TEST_MACHINE_NAME "torturetest"
      38             : 
      39           0 : static bool test_ServerAuth3Crypto(struct dcerpc_pipe *p,
      40             :                                    struct torture_context *tctx,
      41             :                                    uint32_t negotiate_flags,
      42             :                                    struct cli_credentials *machine_credentials,
      43             :                                    bool force_client_rc4)
      44             : {
      45           0 :         struct netr_ServerReqChallenge r;
      46           0 :         struct netr_ServerAuthenticate3 a;
      47           0 :         struct netr_Credential netr_creds1 = {
      48             :                 .data = {0},
      49             :         };
      50           0 :         struct netr_Credential netr_creds2 = {
      51             :                 .data = {0},
      52             :         };
      53           0 :         struct netr_Credential netr_creds3 = {
      54             :                 .data = {0},
      55             :         };
      56           0 :         struct netlogon_creds_CredentialState *creds_state = NULL;
      57           0 :         struct samr_Password machine_password = {
      58             :                 .hash = {0},
      59             :         };
      60           0 :         const char *machine_name = NULL;
      61           0 :         const char *plain_pass = NULL;
      62           0 :         struct dcerpc_binding_handle *b = NULL;
      63           0 :         uint32_t rid = 0;
      64           0 :         NTSTATUS status;
      65           0 :         bool weak_crypto_allowed =
      66           0 :                 (lpcfg_weak_crypto(tctx->lp_ctx) ==
      67             :                  SAMBA_WEAK_CRYPTO_ALLOWED);
      68             : 
      69           0 :         if (p == NULL) {
      70           0 :                 return false;
      71             :         }
      72           0 :         b = p->binding_handle;
      73             : 
      74           0 :         ZERO_STRUCT(r);
      75           0 :         ZERO_STRUCT(a);
      76             : 
      77           0 :         torture_comment(tctx, "client negotiate_flags=0x%08x\n", negotiate_flags);
      78             : 
      79           0 :         machine_name = cli_credentials_get_workstation(machine_credentials);
      80           0 :         torture_assert_not_null(tctx, machine_name, "machine name is not set");
      81             : 
      82           0 :         plain_pass = cli_credentials_get_password(machine_credentials);
      83           0 :         torture_assert_not_null(tctx, plain_pass, "plain_pass is not set");
      84             : 
      85             : 
      86           0 :         torture_comment(tctx, "Testing ServerReqChallenge\n");
      87             : 
      88           0 :         r.in.server_name = NULL;
      89           0 :         r.in.computer_name = machine_name;
      90           0 :         r.in.credentials = &netr_creds1;
      91           0 :         r.out.return_credentials = &netr_creds2;
      92             : 
      93           0 :         netlogon_creds_random_challenge(&netr_creds1);
      94             : 
      95           0 :         status = dcerpc_netr_ServerReqChallenge_r(b, tctx, &r);
      96           0 :         torture_assert_ntstatus_ok(tctx,
      97             :                                    status,
      98             :                                    "ServerReqChallenge failed");
      99           0 :         torture_assert_ntstatus_ok(tctx,
     100             :                                    r.out.result,
     101             :                                    "ServerReqChallenge failed");
     102             : 
     103           0 :         E_md4hash(plain_pass, machine_password.hash);
     104             : 
     105           0 :         a.in.server_name = NULL;
     106           0 :         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
     107           0 :         a.in.secure_channel_type =
     108           0 :                 cli_credentials_get_secure_channel_type(machine_credentials);
     109           0 :         a.in.computer_name = machine_name;
     110           0 :         a.in.negotiate_flags = &negotiate_flags;
     111           0 :         a.in.credentials = &netr_creds3;
     112           0 :         a.out.return_credentials = &netr_creds3;
     113           0 :         a.out.negotiate_flags = &negotiate_flags;
     114           0 :         a.out.rid = &rid;
     115             : 
     116           0 :         if (force_client_rc4) {
     117           0 :                 GNUTLS_FIPS140_SET_LAX_MODE();
     118             :         }
     119           0 :         creds_state = netlogon_creds_client_init(tctx,
     120             :                                                  a.in.account_name,
     121             :                                                  a.in.computer_name,
     122           0 :                                                  a.in.secure_channel_type,
     123             :                                                  &netr_creds1,
     124             :                                                  &netr_creds2,
     125             :                                                  &machine_password,
     126             :                                                  &netr_creds3,
     127             :                                                  negotiate_flags);
     128           0 :         GNUTLS_FIPS140_SET_STRICT_MODE();
     129             :         /* Test that we fail to encrypt with RC4 */
     130           0 :         if (creds_state == NULL &&
     131           0 :             !weak_crypto_allowed && !force_client_rc4 &&
     132           0 :             (negotiate_flags & NETLOGON_NEG_ARCFOUR)) {
     133           0 :                 return false;
     134             :         }
     135           0 :         torture_assert_not_null(tctx,
     136             :                                 creds_state,
     137             :                                 "Failed init netlogon client creds");
     138             : 
     139             : 
     140           0 :         torture_comment(tctx, "Testing ServerAuthenticate3\n");
     141             : 
     142           0 :         status = dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a);
     143           0 :         torture_assert_ntstatus_ok(tctx,
     144             :                                    status,
     145             :                                    "ServerAuthenticate3 failed");
     146             : 
     147             :         /* Check that the server denies RC4 */
     148           0 :         if (!NT_STATUS_IS_OK(a.out.result) &&
     149           0 :             !weak_crypto_allowed &&
     150             :             force_client_rc4) {
     151           0 :                 torture_assert_ntstatus_equal(tctx,
     152             :                                               a.out.result,
     153             :                                               NT_STATUS_DOWNGRADE_DETECTED,
     154             :                                               "Unexpected status code");
     155           0 :                 return false;
     156             :         }
     157           0 :         torture_assert_ntstatus_ok(tctx,
     158             :                                    a.out.result,
     159             :                                    "ServerAuthenticate3 failed");
     160           0 :         torture_assert(tctx,
     161             :                        netlogon_creds_client_check(creds_state, &netr_creds3),
     162             :                        "Credential chaining failed");
     163             : 
     164           0 :         torture_comment(tctx,
     165             :                         "server negotiate_flags=0x%08x\n",
     166             :                         negotiate_flags);
     167             : 
     168           0 :         if (!weak_crypto_allowed) {
     169           0 :                 torture_assert(tctx,
     170             :                                (negotiate_flags & NETLOGON_NEG_ARCFOUR) == 0,
     171             :                                "Server should not announce RC4 support");
     172             :         }
     173             : 
     174             :         /* Prove that requesting a challenge again won't break it */
     175           0 :         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
     176             :                 "ServerReqChallenge failed");
     177           0 :         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
     178             : 
     179           0 :         return true;
     180             : }
     181             : 
     182             : 
     183             : /* Test that we can successfully authenticate using AES. */
     184           0 : static bool test_AES_Crypto(struct torture_context *tctx,
     185             :                             struct dcerpc_pipe *p,
     186             :                             struct cli_credentials *machine_credentials)
     187             : {
     188           0 :         uint32_t negotiate_flags =
     189             :                 NETLOGON_NEG_AUTH2_ADS_FLAGS|
     190             :                 NETLOGON_NEG_SUPPORTS_AES;
     191           0 :         bool ok;
     192             : 
     193           0 :         ok = test_ServerAuth3Crypto(p,
     194             :                                     tctx,
     195             :                                     negotiate_flags,
     196             :                                     machine_credentials,
     197             :                                     false);
     198           0 :         if (!ok) {
     199           0 :                 return false;
     200             :         }
     201             : 
     202           0 :         return true;
     203             : }
     204             : 
     205             : /* If we try to use RC4, the client code should fail to encrypt. */
     206           0 : static bool test_RC4_Crypto_Fail(struct torture_context *tctx,
     207             :                                  struct dcerpc_pipe *p,
     208             :                                  struct cli_credentials *machine_credentials)
     209             : {
     210           0 :         uint32_t negotiate_flags =
     211             :                 NETLOGON_NEG_AUTH2_ADS_FLAGS|
     212             :                 NETLOGON_NEG_ARCFOUR;
     213           0 :         bool ok;
     214             : 
     215           0 :         ok = test_ServerAuth3Crypto(p,
     216             :                                     tctx,
     217             :                                     negotiate_flags,
     218             :                                     machine_credentials,
     219             :                                     false);
     220           0 :         if (!ok) {
     221           0 :                 return true;
     222             :         }
     223             : 
     224           0 :         return false;
     225             : }
     226             : 
     227             : /*
     228             :  * Enforce the use of RC4 and try to authenticate. The server should fail
     229             :  * in this case as it doesn't allow RC4
     230             :  */
     231           0 : static bool test_RC4_Crypto_Force(struct torture_context *tctx,
     232             :                                   struct dcerpc_pipe *p,
     233             :                                   struct cli_credentials *machine_credentials)
     234             : {
     235           0 :         uint32_t negotiate_flags =
     236             :                 NETLOGON_NEG_AUTH2_ADS_FLAGS|
     237             :                 NETLOGON_NEG_ARCFOUR;
     238           0 :         bool ok;
     239             : 
     240           0 :         ok = test_ServerAuth3Crypto(p,
     241             :                                     tctx,
     242             :                                     negotiate_flags,
     243             :                                     machine_credentials,
     244             :                                     true);
     245           0 :         if (!ok) {
     246           0 :                 return true;
     247             :         }
     248             : 
     249           0 :         return false;
     250             : }
     251             : 
     252        2354 : struct torture_suite *torture_rpc_netlogon_crypto_fips(TALLOC_CTX *mem_ctx)
     253             : {
     254        2354 :         struct torture_suite *suite = torture_suite_create(mem_ctx,
     255             :                                                            "fips.netlogon.crypto");
     256        2354 :         struct torture_rpc_tcase *tcase = NULL;
     257             : 
     258        2354 :         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite,
     259             :                                                               "netlogon",
     260             :                                                               &ndr_table_netlogon,
     261             :                                                               TEST_MACHINE_NAME);
     262             : 
     263        2354 :         torture_rpc_tcase_add_test_creds(tcase,
     264             :                                          "test_AES_Crytpo",
     265             :                                          test_AES_Crypto);
     266        2354 :         torture_rpc_tcase_add_test_creds(tcase,
     267             :                                          "test_RC4_Crytpo_Fail",
     268             :                                          test_RC4_Crypto_Fail);
     269        2354 :         torture_rpc_tcase_add_test_creds(tcase,
     270             :                                          "test_RC4_Crytpo_Force",
     271             :                                          test_RC4_Crypto_Force);
     272             : 
     273        2354 :         return suite;
     274             : }

Generated by: LCOV version 1.14