1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
6#include "base/bind.h"
7#include "base/message_loop/message_loop.h"
8#include "base/run_loop.h"
9#include "base/synchronization/waitable_event.h"
10#include "remoting/host/dns_blackhole_checker.h"
11#include "remoting/host/policy_hack/fake_policy_watcher.h"
12#include "remoting/host/policy_hack/mock_policy_callback.h"
13#include "remoting/host/policy_hack/policy_watcher.h"
14#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace remoting {
18namespace policy_hack {
19
20class PolicyWatcherTest : public testing::Test {
21 public:
22  PolicyWatcherTest() {
23  }
24
25  virtual void SetUp() OVERRIDE {
26    message_loop_proxy_ = base::MessageLoopProxy::current();
27    policy_callback_ = base::Bind(&MockPolicyCallback::OnPolicyUpdate,
28                                  base::Unretained(&mock_policy_callback_));
29    policy_watcher_.reset(new FakePolicyWatcher(message_loop_proxy_));
30    nat_true_.SetBoolean(PolicyWatcher::kNatPolicyName, true);
31    nat_false_.SetBoolean(PolicyWatcher::kNatPolicyName, false);
32    nat_one_.SetInteger(PolicyWatcher::kNatPolicyName, 1);
33    domain_empty_.SetString(PolicyWatcher::kHostDomainPolicyName,
34                            std::string());
35    domain_full_.SetString(PolicyWatcher::kHostDomainPolicyName, kHostDomain);
36    SetDefaults(nat_true_others_default_);
37    nat_true_others_default_.SetBoolean(PolicyWatcher::kNatPolicyName, true);
38    SetDefaults(nat_false_others_default_);
39    nat_false_others_default_.SetBoolean(PolicyWatcher::kNatPolicyName, false);
40    SetDefaults(domain_empty_others_default_);
41    domain_empty_others_default_.SetString(PolicyWatcher::kHostDomainPolicyName,
42                                           std::string());
43    SetDefaults(domain_full_others_default_);
44    domain_full_others_default_.SetString(PolicyWatcher::kHostDomainPolicyName,
45                                          kHostDomain);
46    nat_true_domain_empty_.SetBoolean(PolicyWatcher::kNatPolicyName, true);
47    nat_true_domain_empty_.SetString(PolicyWatcher::kHostDomainPolicyName,
48                                     std::string());
49    nat_true_domain_full_.SetBoolean(PolicyWatcher::kNatPolicyName, true);
50    nat_true_domain_full_.SetString(PolicyWatcher::kHostDomainPolicyName,
51                                   kHostDomain);
52    nat_false_domain_empty_.SetBoolean(PolicyWatcher::kNatPolicyName, false);
53    nat_false_domain_empty_.SetString(PolicyWatcher::kHostDomainPolicyName,
54                                      std::string());
55    nat_false_domain_full_.SetBoolean(PolicyWatcher::kNatPolicyName, false);
56    nat_false_domain_full_.SetString(PolicyWatcher::kHostDomainPolicyName,
57                                    kHostDomain);
58    SetDefaults(nat_true_domain_empty_others_default_);
59    nat_true_domain_empty_others_default_.SetBoolean(
60        PolicyWatcher::kNatPolicyName, true);
61    nat_true_domain_empty_others_default_.SetString(
62        PolicyWatcher::kHostDomainPolicyName, std::string());
63    unknown_policies_.SetString("UnknownPolicyOne", std::string());
64    unknown_policies_.SetString("UnknownPolicyTwo", std::string());
65
66    const char kOverrideNatTraversalToFalse[] =
67      "{ \"RemoteAccessHostFirewallTraversal\": false }";
68    nat_true_and_overridden_.SetBoolean(PolicyWatcher::kNatPolicyName, true);
69    nat_true_and_overridden_.SetString(
70        PolicyWatcher::kHostDebugOverridePoliciesName,
71        kOverrideNatTraversalToFalse);
72    pairing_true_.SetBoolean(PolicyWatcher::kHostAllowClientPairing, true);
73    pairing_false_.SetBoolean(PolicyWatcher::kHostAllowClientPairing, false);
74    gnubby_auth_true_.SetBoolean(PolicyWatcher::kHostAllowGnubbyAuthPolicyName,
75                                 true);
76    gnubby_auth_false_.SetBoolean(PolicyWatcher::kHostAllowGnubbyAuthPolicyName,
77                                 false);
78    relay_true_.SetBoolean(PolicyWatcher::kRelayPolicyName, true);
79    relay_false_.SetBoolean(PolicyWatcher::kRelayPolicyName, false);
80    port_range_full_.SetString(PolicyWatcher::kUdpPortRangePolicyName,
81                               kPortRange);
82    port_range_empty_.SetString(PolicyWatcher::kUdpPortRangePolicyName,
83                                std::string());
84
85#if !defined(NDEBUG)
86    SetDefaults(nat_false_overridden_others_default_);
87    nat_false_overridden_others_default_.SetBoolean(
88        PolicyWatcher::kNatPolicyName, false);
89    nat_false_overridden_others_default_.SetString(
90        PolicyWatcher::kHostDebugOverridePoliciesName,
91        kOverrideNatTraversalToFalse);
92#endif
93  }
94
95 protected:
96  void StartWatching() {
97    policy_watcher_->StartWatching(policy_callback_);
98    base::RunLoop().RunUntilIdle();
99  }
100
101  void StopWatching() {
102    base::WaitableEvent stop_event(false, false);
103    policy_watcher_->StopWatching(&stop_event);
104    base::RunLoop().RunUntilIdle();
105    EXPECT_EQ(true, stop_event.IsSignaled());
106  }
107
108  static const char* kHostDomain;
109  static const char* kPortRange;
110  base::MessageLoop message_loop_;
111  scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
112  MockPolicyCallback mock_policy_callback_;
113  PolicyWatcher::PolicyCallback policy_callback_;
114  scoped_ptr<FakePolicyWatcher> policy_watcher_;
115  base::DictionaryValue empty_;
116  base::DictionaryValue nat_true_;
117  base::DictionaryValue nat_false_;
118  base::DictionaryValue nat_one_;
119  base::DictionaryValue domain_empty_;
120  base::DictionaryValue domain_full_;
121  base::DictionaryValue nat_true_others_default_;
122  base::DictionaryValue nat_false_others_default_;
123  base::DictionaryValue domain_empty_others_default_;
124  base::DictionaryValue domain_full_others_default_;
125  base::DictionaryValue nat_true_domain_empty_;
126  base::DictionaryValue nat_true_domain_full_;
127  base::DictionaryValue nat_false_domain_empty_;
128  base::DictionaryValue nat_false_domain_full_;
129  base::DictionaryValue nat_true_domain_empty_others_default_;
130  base::DictionaryValue unknown_policies_;
131  base::DictionaryValue nat_true_and_overridden_;
132  base::DictionaryValue nat_false_overridden_others_default_;
133  base::DictionaryValue pairing_true_;
134  base::DictionaryValue pairing_false_;
135  base::DictionaryValue gnubby_auth_true_;
136  base::DictionaryValue gnubby_auth_false_;
137  base::DictionaryValue relay_true_;
138  base::DictionaryValue relay_false_;
139  base::DictionaryValue port_range_full_;
140  base::DictionaryValue port_range_empty_;
141
142 private:
143  void SetDefaults(base::DictionaryValue& dict) {
144    dict.SetBoolean(PolicyWatcher::kNatPolicyName, true);
145    dict.SetBoolean(PolicyWatcher::kRelayPolicyName, true);
146    dict.SetString(PolicyWatcher::kUdpPortRangePolicyName, "");
147    dict.SetBoolean(PolicyWatcher::kHostRequireTwoFactorPolicyName, false);
148    dict.SetString(PolicyWatcher::kHostDomainPolicyName, std::string());
149    dict.SetBoolean(PolicyWatcher::kHostMatchUsernamePolicyName, false);
150    dict.SetString(PolicyWatcher::kHostTalkGadgetPrefixPolicyName,
151                   kDefaultHostTalkGadgetPrefix);
152    dict.SetBoolean(PolicyWatcher::kHostRequireCurtainPolicyName, false);
153    dict.SetString(PolicyWatcher::kHostTokenUrlPolicyName, std::string());
154    dict.SetString(PolicyWatcher::kHostTokenValidationUrlPolicyName,
155                   std::string());
156    dict.SetString(PolicyWatcher::kHostTokenValidationCertIssuerPolicyName,
157                   std::string());
158    dict.SetBoolean(PolicyWatcher::kHostAllowClientPairing, true);
159    dict.SetBoolean(PolicyWatcher::kHostAllowGnubbyAuthPolicyName, true);
160#if !defined(NDEBUG)
161    dict.SetString(PolicyWatcher::kHostDebugOverridePoliciesName, "");
162#endif
163  }
164};
165
166const char* PolicyWatcherTest::kHostDomain = "google.com";
167const char* PolicyWatcherTest::kPortRange = "12400-12409";
168
169MATCHER_P(IsPolicies, dict, "") {
170  return arg->Equals(dict);
171}
172
173TEST_F(PolicyWatcherTest, None) {
174  EXPECT_CALL(mock_policy_callback_,
175              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
176
177  StartWatching();
178  policy_watcher_->SetPolicies(&empty_);
179  StopWatching();
180}
181
182TEST_F(PolicyWatcherTest, NatTrue) {
183  EXPECT_CALL(mock_policy_callback_,
184              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
185
186  StartWatching();
187  policy_watcher_->SetPolicies(&nat_true_);
188  StopWatching();
189}
190
191TEST_F(PolicyWatcherTest, NatFalse) {
192  EXPECT_CALL(mock_policy_callback_,
193              OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_)));
194
195  StartWatching();
196  policy_watcher_->SetPolicies(&nat_false_);
197  StopWatching();
198}
199
200TEST_F(PolicyWatcherTest, NatOne) {
201  EXPECT_CALL(mock_policy_callback_,
202              OnPolicyUpdatePtr(IsPolicies(&nat_false_others_default_)));
203
204  StartWatching();
205  policy_watcher_->SetPolicies(&nat_one_);
206  StopWatching();
207}
208
209TEST_F(PolicyWatcherTest, DomainEmpty) {
210  EXPECT_CALL(mock_policy_callback_,
211              OnPolicyUpdatePtr(IsPolicies(&domain_empty_others_default_)));
212
213  StartWatching();
214  policy_watcher_->SetPolicies(&domain_empty_);
215  StopWatching();
216}
217
218TEST_F(PolicyWatcherTest, DomainFull) {
219  EXPECT_CALL(mock_policy_callback_,
220              OnPolicyUpdatePtr(IsPolicies(&domain_full_others_default_)));
221
222  StartWatching();
223  policy_watcher_->SetPolicies(&domain_full_);
224  StopWatching();
225}
226
227TEST_F(PolicyWatcherTest, NatNoneThenTrue) {
228  EXPECT_CALL(mock_policy_callback_,
229              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
230
231  StartWatching();
232  policy_watcher_->SetPolicies(&empty_);
233  policy_watcher_->SetPolicies(&nat_true_);
234  StopWatching();
235}
236
237TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrue) {
238  EXPECT_CALL(mock_policy_callback_,
239              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
240
241  StartWatching();
242  policy_watcher_->SetPolicies(&empty_);
243  policy_watcher_->SetPolicies(&nat_true_);
244  policy_watcher_->SetPolicies(&nat_true_);
245  StopWatching();
246}
247
248TEST_F(PolicyWatcherTest, NatNoneThenTrueThenTrueThenFalse) {
249  testing::InSequence sequence;
250  EXPECT_CALL(mock_policy_callback_,
251              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
252  EXPECT_CALL(mock_policy_callback_,
253              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
254
255  StartWatching();
256  policy_watcher_->SetPolicies(&empty_);
257  policy_watcher_->SetPolicies(&nat_true_);
258  policy_watcher_->SetPolicies(&nat_true_);
259  policy_watcher_->SetPolicies(&nat_false_);
260  StopWatching();
261}
262
263TEST_F(PolicyWatcherTest, NatNoneThenFalse) {
264  testing::InSequence sequence;
265  EXPECT_CALL(mock_policy_callback_,
266              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
267  EXPECT_CALL(mock_policy_callback_,
268              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
269
270  StartWatching();
271  policy_watcher_->SetPolicies(&empty_);
272  policy_watcher_->SetPolicies(&nat_false_);
273  StopWatching();
274}
275
276TEST_F(PolicyWatcherTest, NatNoneThenFalseThenTrue) {
277  testing::InSequence sequence;
278  EXPECT_CALL(mock_policy_callback_,
279              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
280  EXPECT_CALL(mock_policy_callback_,
281              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
282  EXPECT_CALL(mock_policy_callback_,
283              OnPolicyUpdatePtr(IsPolicies(&nat_true_)));
284
285  StartWatching();
286  policy_watcher_->SetPolicies(&empty_);
287  policy_watcher_->SetPolicies(&nat_false_);
288  policy_watcher_->SetPolicies(&nat_true_);
289  StopWatching();
290}
291
292TEST_F(PolicyWatcherTest, ChangeOneRepeatedlyThenTwo) {
293  testing::InSequence sequence;
294  EXPECT_CALL(mock_policy_callback_,
295              OnPolicyUpdatePtr(IsPolicies(
296                  &nat_true_domain_empty_others_default_)));
297  EXPECT_CALL(mock_policy_callback_,
298              OnPolicyUpdatePtr(IsPolicies(&domain_full_)));
299  EXPECT_CALL(mock_policy_callback_,
300              OnPolicyUpdatePtr(IsPolicies(&nat_false_)));
301  EXPECT_CALL(mock_policy_callback_,
302              OnPolicyUpdatePtr(IsPolicies(&domain_empty_)));
303  EXPECT_CALL(mock_policy_callback_,
304              OnPolicyUpdatePtr(IsPolicies(&nat_true_domain_full_)));
305
306  StartWatching();
307  policy_watcher_->SetPolicies(&nat_true_domain_empty_);
308  policy_watcher_->SetPolicies(&nat_true_domain_full_);
309  policy_watcher_->SetPolicies(&nat_false_domain_full_);
310  policy_watcher_->SetPolicies(&nat_false_domain_empty_);
311  policy_watcher_->SetPolicies(&nat_true_domain_full_);
312  StopWatching();
313}
314
315TEST_F(PolicyWatcherTest, FilterUnknownPolicies) {
316  testing::InSequence sequence;
317  EXPECT_CALL(mock_policy_callback_,
318              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
319
320  StartWatching();
321  policy_watcher_->SetPolicies(&empty_);
322  policy_watcher_->SetPolicies(&unknown_policies_);
323  policy_watcher_->SetPolicies(&empty_);
324  StopWatching();
325}
326
327TEST_F(PolicyWatcherTest, DebugOverrideNatPolicy) {
328#if !defined(NDEBUG)
329  EXPECT_CALL(mock_policy_callback_,
330      OnPolicyUpdatePtr(IsPolicies(&nat_false_overridden_others_default_)));
331#else
332  EXPECT_CALL(mock_policy_callback_,
333      OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
334#endif
335
336  StartWatching();
337  policy_watcher_->SetPolicies(&nat_true_and_overridden_);
338  StopWatching();
339}
340
341TEST_F(PolicyWatcherTest, PairingFalseThenTrue) {
342  testing::InSequence sequence;
343  EXPECT_CALL(mock_policy_callback_,
344              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
345  EXPECT_CALL(mock_policy_callback_,
346              OnPolicyUpdatePtr(IsPolicies(&pairing_false_)));
347  EXPECT_CALL(mock_policy_callback_,
348              OnPolicyUpdatePtr(IsPolicies(&pairing_true_)));
349
350  StartWatching();
351  policy_watcher_->SetPolicies(&empty_);
352  policy_watcher_->SetPolicies(&pairing_false_);
353  policy_watcher_->SetPolicies(&pairing_true_);
354  StopWatching();
355}
356
357TEST_F(PolicyWatcherTest, GnubbyAuth) {
358  testing::InSequence sequence;
359  EXPECT_CALL(mock_policy_callback_,
360              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
361  EXPECT_CALL(mock_policy_callback_,
362              OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_false_)));
363  EXPECT_CALL(mock_policy_callback_,
364              OnPolicyUpdatePtr(IsPolicies(&gnubby_auth_true_)));
365
366  StartWatching();
367  policy_watcher_->SetPolicies(&empty_);
368  policy_watcher_->SetPolicies(&gnubby_auth_false_);
369  policy_watcher_->SetPolicies(&gnubby_auth_true_);
370  StopWatching();
371}
372
373TEST_F(PolicyWatcherTest, Relay) {
374  testing::InSequence sequence;
375  EXPECT_CALL(mock_policy_callback_,
376              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
377  EXPECT_CALL(mock_policy_callback_,
378              OnPolicyUpdatePtr(IsPolicies(&relay_false_)));
379  EXPECT_CALL(mock_policy_callback_,
380              OnPolicyUpdatePtr(IsPolicies(&relay_true_)));
381
382  StartWatching();
383  policy_watcher_->SetPolicies(&empty_);
384  policy_watcher_->SetPolicies(&relay_false_);
385  policy_watcher_->SetPolicies(&relay_true_);
386  StopWatching();
387}
388
389TEST_F(PolicyWatcherTest, UdpPortRange) {
390  testing::InSequence sequence;
391  EXPECT_CALL(mock_policy_callback_,
392              OnPolicyUpdatePtr(IsPolicies(&nat_true_others_default_)));
393  EXPECT_CALL(mock_policy_callback_,
394              OnPolicyUpdatePtr(IsPolicies(&port_range_full_)));
395  EXPECT_CALL(mock_policy_callback_,
396              OnPolicyUpdatePtr(IsPolicies(&port_range_empty_)));
397
398  StartWatching();
399  policy_watcher_->SetPolicies(&empty_);
400  policy_watcher_->SetPolicies(&port_range_full_);
401  policy_watcher_->SetPolicies(&port_range_empty_);
402  StopWatching();
403}
404
405}  // namespace policy_hack
406}  // namespace remoting
407