2 Unix SMB/CIFS implementation.
4 test suite for netlogon rpc operations
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
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.
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.
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/>.
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"
37 #define TEST_MACHINE_NAME "torturetest"
39 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
)
45 struct netr_ServerReqChallenge r
;
46 struct netr_ServerAuthenticate3 a
;
47 struct netr_Credential netr_creds1
= {
50 struct netr_Credential netr_creds2
= {
53 struct netr_Credential netr_creds3
= {
56 struct netlogon_creds_CredentialState
*creds_state
= NULL
;
57 struct samr_Password machine_password
= {
60 const char *machine_name
= NULL
;
61 const char *plain_pass
= NULL
;
62 struct dcerpc_binding_handle
*b
= NULL
;
65 bool weak_crypto_allowed
=
66 (lpcfg_weak_crypto(tctx
->lp_ctx
) ==
67 SAMBA_WEAK_CRYPTO_ALLOWED
);
72 b
= p
->binding_handle
;
77 torture_comment(tctx
, "client negotiate_flags=0x%08x\n", negotiate_flags
);
79 machine_name
= cli_credentials_get_workstation(machine_credentials
);
80 torture_assert_not_null(tctx
, machine_name
, "machine name is not set");
82 plain_pass
= cli_credentials_get_password(machine_credentials
);
83 torture_assert_not_null(tctx
, plain_pass
, "plain_pass is not set");
86 torture_comment(tctx
, "Testing ServerReqChallenge\n");
88 r
.in
.server_name
= NULL
;
89 r
.in
.computer_name
= machine_name
;
90 r
.in
.credentials
= &netr_creds1
;
91 r
.out
.return_credentials
= &netr_creds2
;
93 netlogon_creds_random_challenge(&netr_creds1
);
95 status
= dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
);
96 torture_assert_ntstatus_ok(tctx
,
98 "ServerReqChallenge failed");
99 torture_assert_ntstatus_ok(tctx
,
101 "ServerReqChallenge failed");
103 E_md4hash(plain_pass
, machine_password
.hash
);
105 a
.in
.server_name
= NULL
;
106 a
.in
.account_name
= talloc_asprintf(tctx
, "%s$", machine_name
);
107 a
.in
.secure_channel_type
=
108 cli_credentials_get_secure_channel_type(machine_credentials
);
109 a
.in
.computer_name
= machine_name
;
110 a
.in
.negotiate_flags
= &negotiate_flags
;
111 a
.in
.credentials
= &netr_creds3
;
112 a
.out
.return_credentials
= &netr_creds3
;
113 a
.out
.negotiate_flags
= &negotiate_flags
;
116 if (force_client_rc4
) {
117 GNUTLS_FIPS140_SET_LAX_MODE();
119 creds_state
= netlogon_creds_client_init(tctx
,
122 a
.in
.secure_channel_type
,
129 GNUTLS_FIPS140_SET_STRICT_MODE();
130 /* Test that we fail to encrypt with RC4 */
131 if (creds_state
== NULL
&&
132 !weak_crypto_allowed
&& !force_client_rc4
&&
133 (negotiate_flags
& NETLOGON_NEG_ARCFOUR
)) {
136 torture_assert_not_null(tctx
,
138 "Failed init netlogon client creds");
141 torture_comment(tctx
, "Testing ServerAuthenticate3\n");
143 status
= dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
);
144 torture_assert_ntstatus_ok(tctx
,
146 "ServerAuthenticate3 failed");
148 /* Check that the server denies RC4 */
149 if (!NT_STATUS_IS_OK(a
.out
.result
) &&
150 !weak_crypto_allowed
&&
152 torture_assert_ntstatus_equal(tctx
,
154 NT_STATUS_DOWNGRADE_DETECTED
,
155 "Unexpected status code");
156 torture_assert_int_equal(tctx
, negotiate_flags
, 0,
157 "NT_STATUS_DOWNGRADE_DETECTED...");
160 torture_assert_ntstatus_ok(tctx
,
162 "ServerAuthenticate3 failed");
164 netlogon_creds_client_check(creds_state
, &netr_creds3
),
165 "Credential chaining failed");
167 torture_comment(tctx
,
168 "server negotiate_flags=0x%08x\n",
171 if (!weak_crypto_allowed
) {
173 (negotiate_flags
& NETLOGON_NEG_SUPPORTS_AES
),
174 "Server negotiate AES support");
177 /* Prove that requesting a challenge again won't break it */
178 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
179 "ServerReqChallenge failed");
180 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
186 /* Test that we can successfully authenticate using AES. */
187 static bool test_AES_Crypto(struct torture_context
*tctx
,
188 struct dcerpc_pipe
*p
,
189 struct cli_credentials
*machine_credentials
)
191 uint32_t negotiate_flags
=
192 NETLOGON_NEG_AUTH2_ADS_FLAGS
|
193 NETLOGON_NEG_SUPPORTS_AES
;
196 ok
= test_ServerAuth3Crypto(p
,
208 /* If we try to use RC4, the client code should fail to encrypt. */
209 static bool test_RC4_Crypto_Fail(struct torture_context
*tctx
,
210 struct dcerpc_pipe
*p
,
211 struct cli_credentials
*machine_credentials
)
213 uint32_t negotiate_flags
=
214 NETLOGON_NEG_AUTH2_ADS_FLAGS
|
215 NETLOGON_NEG_ARCFOUR
;
218 ok
= test_ServerAuth3Crypto(p
,
231 * Enforce the use of RC4 and try to authenticate. The server should fail
232 * in this case as it doesn't allow RC4
234 static bool test_RC4_Crypto_Force(struct torture_context
*tctx
,
235 struct dcerpc_pipe
*p
,
236 struct cli_credentials
*machine_credentials
)
238 uint32_t negotiate_flags
=
239 NETLOGON_NEG_AUTH2_ADS_FLAGS
|
240 NETLOGON_NEG_ARCFOUR
;
243 ok
= test_ServerAuth3Crypto(p
,
255 struct torture_suite
*torture_rpc_netlogon_crypto_fips(TALLOC_CTX
*mem_ctx
)
257 struct torture_suite
*suite
= torture_suite_create(mem_ctx
,
258 "fips.netlogon.crypto");
259 struct torture_rpc_tcase
*tcase
= NULL
;
261 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
,
266 torture_rpc_tcase_add_test_creds(tcase
,
269 torture_rpc_tcase_add_test_creds(tcase
,
270 "test_RC4_Crytpo_Fail",
271 test_RC4_Crypto_Fail
);
272 torture_rpc_tcase_add_test_creds(tcase
,
273 "test_RC4_Crytpo_Force",
274 test_RC4_Crypto_Force
);