ctdb-scripts: Support storing statd-callout state in cluster filesystem
[samba4-gss.git] / source4 / torture / rpc / netlogon_crypto.c
blob858a17e0ea8b168b65c72b80a1f694e3de745dea
1 /*
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/>.
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"
35 #undef strcasecmp
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 = {
48 .data = {0},
50 struct netr_Credential netr_creds2 = {
51 .data = {0},
53 struct netr_Credential netr_creds3 = {
54 .data = {0},
56 struct netlogon_creds_CredentialState *creds_state = NULL;
57 struct samr_Password machine_password = {
58 .hash = {0},
60 const char *machine_name = NULL;
61 const char *plain_pass = NULL;
62 struct dcerpc_binding_handle *b = NULL;
63 uint32_t rid = 0;
64 NTSTATUS status;
65 bool weak_crypto_allowed =
66 (lpcfg_weak_crypto(tctx->lp_ctx) ==
67 SAMBA_WEAK_CRYPTO_ALLOWED);
69 if (p == NULL) {
70 return false;
72 b = p->binding_handle;
74 ZERO_STRUCT(r);
75 ZERO_STRUCT(a);
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,
97 status,
98 "ServerReqChallenge failed");
99 torture_assert_ntstatus_ok(tctx,
100 r.out.result,
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;
114 a.out.rid = &rid;
116 if (force_client_rc4) {
117 GNUTLS_FIPS140_SET_LAX_MODE();
119 creds_state = netlogon_creds_client_init(tctx,
120 a.in.account_name,
121 a.in.computer_name,
122 a.in.secure_channel_type,
123 &netr_creds1,
124 &netr_creds2,
125 &machine_password,
126 &netr_creds3,
127 negotiate_flags,
128 negotiate_flags);
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)) {
134 return false;
136 torture_assert_not_null(tctx,
137 creds_state,
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,
145 status,
146 "ServerAuthenticate3 failed");
148 /* Check that the server denies RC4 */
149 if (!NT_STATUS_IS_OK(a.out.result) &&
150 !weak_crypto_allowed &&
151 force_client_rc4) {
152 torture_assert_ntstatus_equal(tctx,
153 a.out.result,
154 NT_STATUS_DOWNGRADE_DETECTED,
155 "Unexpected status code");
156 torture_assert_int_equal(tctx, negotiate_flags, 0,
157 "NT_STATUS_DOWNGRADE_DETECTED...");
158 return false;
160 torture_assert_ntstatus_ok(tctx,
161 a.out.result,
162 "ServerAuthenticate3 failed");
163 torture_assert(tctx,
164 netlogon_creds_client_check(creds_state, &netr_creds3),
165 "Credential chaining failed");
167 torture_comment(tctx,
168 "server negotiate_flags=0x%08x\n",
169 negotiate_flags);
171 if (!weak_crypto_allowed) {
172 torture_assert(tctx,
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");
182 return true;
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;
194 bool ok;
196 ok = test_ServerAuth3Crypto(p,
197 tctx,
198 negotiate_flags,
199 machine_credentials,
200 false);
201 if (!ok) {
202 return false;
205 return true;
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;
216 bool ok;
218 ok = test_ServerAuth3Crypto(p,
219 tctx,
220 negotiate_flags,
221 machine_credentials,
222 false);
223 if (!ok) {
224 return true;
227 return false;
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;
241 bool ok;
243 ok = test_ServerAuth3Crypto(p,
244 tctx,
245 negotiate_flags,
246 machine_credentials,
247 true);
248 if (!ok) {
249 return true;
252 return false;
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,
262 "netlogon",
263 &ndr_table_netlogon,
264 TEST_MACHINE_NAME);
266 torture_rpc_tcase_add_test_creds(tcase,
267 "test_AES_Crytpo",
268 test_AES_Crypto);
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);
276 return suite;