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 : }
|