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
,
128 GNUTLS_FIPS140_SET_STRICT_MODE();
129 /* Test that we fail to encrypt with RC4 */
130 if (creds_state
== NULL
&&
131 !weak_crypto_allowed
&& !force_client_rc4
&&
132 (negotiate_flags
& NETLOGON_NEG_ARCFOUR
)) {
135 torture_assert_not_null(tctx
,
137 "Failed init netlogon client creds");
140 torture_comment(tctx
, "Testing ServerAuthenticate3\n");
142 status
= dcerpc_netr_ServerAuthenticate3_r(b
, tctx
, &a
);
143 torture_assert_ntstatus_ok(tctx
,
145 "ServerAuthenticate3 failed");
147 /* Check that the server denies RC4 */
148 if (!NT_STATUS_IS_OK(a
.out
.result
) &&
149 !weak_crypto_allowed
&&
151 torture_assert_ntstatus_equal(tctx
,
153 NT_STATUS_DOWNGRADE_DETECTED
,
154 "Unexpected status code");
157 torture_assert_ntstatus_ok(tctx
,
159 "ServerAuthenticate3 failed");
161 netlogon_creds_client_check(creds_state
, &netr_creds3
),
162 "Credential chaining failed");
164 torture_comment(tctx
,
165 "server negotiate_flags=0x%08x\n",
168 if (!weak_crypto_allowed
) {
170 (negotiate_flags
& NETLOGON_NEG_ARCFOUR
) == 0,
171 "Server should not announce RC4 support");
174 /* Prove that requesting a challenge again won't break it */
175 torture_assert_ntstatus_ok(tctx
, dcerpc_netr_ServerReqChallenge_r(b
, tctx
, &r
),
176 "ServerReqChallenge failed");
177 torture_assert_ntstatus_ok(tctx
, r
.out
.result
, "ServerReqChallenge failed");
183 /* Test that we can successfully authenticate using AES. */
184 static bool test_AES_Crypto(struct torture_context
*tctx
,
185 struct dcerpc_pipe
*p
,
186 struct cli_credentials
*machine_credentials
)
188 uint32_t negotiate_flags
=
189 NETLOGON_NEG_AUTH2_ADS_FLAGS
|
190 NETLOGON_NEG_SUPPORTS_AES
;
193 ok
= test_ServerAuth3Crypto(p
,
205 /* If we try to use RC4, the client code should fail to encrypt. */
206 static bool test_RC4_Crypto_Fail(struct torture_context
*tctx
,
207 struct dcerpc_pipe
*p
,
208 struct cli_credentials
*machine_credentials
)
210 uint32_t negotiate_flags
=
211 NETLOGON_NEG_AUTH2_ADS_FLAGS
|
212 NETLOGON_NEG_ARCFOUR
;
215 ok
= test_ServerAuth3Crypto(p
,
228 * Enforce the use of RC4 and try to authenticate. The server should fail
229 * in this case as it doesn't allow RC4
231 static bool test_RC4_Crypto_Force(struct torture_context
*tctx
,
232 struct dcerpc_pipe
*p
,
233 struct cli_credentials
*machine_credentials
)
235 uint32_t negotiate_flags
=
236 NETLOGON_NEG_AUTH2_ADS_FLAGS
|
237 NETLOGON_NEG_ARCFOUR
;
240 ok
= test_ServerAuth3Crypto(p
,
252 struct torture_suite
*torture_rpc_netlogon_crypto_fips(TALLOC_CTX
*mem_ctx
)
254 struct torture_suite
*suite
= torture_suite_create(mem_ctx
,
255 "fips.netlogon.crypto");
256 struct torture_rpc_tcase
*tcase
= NULL
;
258 tcase
= torture_suite_add_machine_bdc_rpc_iface_tcase(suite
,
263 torture_rpc_tcase_add_test_creds(tcase
,
266 torture_rpc_tcase_add_test_creds(tcase
,
267 "test_RC4_Crytpo_Fail",
268 test_RC4_Crypto_Fail
);
269 torture_rpc_tcase_add_test_creds(tcase
,
270 "test_RC4_Crytpo_Force",
271 test_RC4_Crypto_Force
);