1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "remoting/host/pairing_registry_delegate_win.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <shlwapi.h>
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/guid.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/values.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/win/registry.h"
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace remoting {
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using protocol::PairingRegistry;
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class PairingRegistryDelegateWinTest : public testing::Test {
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    key_name_ = base::GenerateGUID();
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::win::RegKey root;
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(root.Create(HKEY_CURRENT_USER,
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            base::UTF8ToWide(key_name_).c_str(),
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                            KEY_READ | KEY_WRITE) == ERROR_SUCCESS);
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_TRUE(privileged_.Create(root.Handle(), L"privileged",
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                   KEY_READ | KEY_WRITE) == ERROR_SUCCESS);
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_TRUE(unprivileged_.Create(root.Handle(), L"unprivileged",
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                     KEY_READ | KEY_WRITE) == ERROR_SUCCESS);
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    privileged_.Close();
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    unprivileged_.Close();
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SHDeleteKey(HKEY_CURRENT_USER,
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    base::UTF8ToWide(key_name_).c_str()) == ERROR_SUCCESS);
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) protected:
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string key_name_;
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::win::RegKey privileged_;
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::win::RegKey unprivileged_;
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(PairingRegistryDelegateWinTest, SaveAndLoad) {
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<PairingRegistryDelegateWin> delegate(
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new PairingRegistryDelegateWin());
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Check that registry is initially empty.
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(delegate->LoadAll()->empty());
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Add a couple of pairings.
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PairingRegistry::Pairing pairing1(base::Time::Now(), "xxx", "xxx", "xxx");
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PairingRegistry::Pairing pairing2(base::Time::Now(), "yyy", "yyy", "yyy");
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(delegate->Save(pairing1));
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(delegate->Save(pairing2));
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Verify that there are two pairings in the store now.
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(delegate->LoadAll()->GetSize(), 2u);
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Verify that they can be retrieved.
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(delegate->Load(pairing1.client_id()), pairing1);
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(delegate->Load(pairing2.client_id()), pairing2);
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Delete the first pairing.
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(delegate->Delete(pairing1.client_id()));
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Verify that there is only one pairing left.
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(delegate->Load(pairing1.client_id()), PairingRegistry::Pairing());
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(delegate->Load(pairing2.client_id()), pairing2);
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Verify that the only remaining value is |pairing2|.
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(delegate->LoadAll()->GetSize(), 1u);
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<base::ListValue> pairings = delegate->LoadAll();
80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  base::DictionaryValue* json;
81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_TRUE(pairings->GetDictionary(0, &json));
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(PairingRegistry::Pairing::CreateFromValue(*json), pairing2);
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Delete the rest and verify.
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(delegate->DeleteAll());
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(delegate->LoadAll()->empty());
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Verifies that the delegate is stateless by using two different instances.
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(PairingRegistryDelegateWinTest, Stateless) {
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<PairingRegistryDelegateWin> load_delegate(
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new PairingRegistryDelegateWin());
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  load_delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<PairingRegistryDelegateWin> save_delegate(
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new PairingRegistryDelegateWin());
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  save_delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PairingRegistry::Pairing pairing(base::Time::Now(), "xxx", "xxx", "xxx");
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(save_delegate->Save(pairing));
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(load_delegate->Load(pairing.client_id()), pairing);
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(PairingRegistryDelegateWinTest, Unprivileged) {
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<PairingRegistryDelegateWin> delegate(
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      new PairingRegistryDelegateWin());
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PairingRegistry::Pairing pairing(base::Time::Now(), "xxx", "xxx", "xxx");
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(delegate->Save(pairing));
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(delegate->Load(pairing.client_id()), pairing);
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Strip the delegate from write access and validate that it still can be used
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // to read the pairings.
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  delegate.reset(new PairingRegistryDelegateWin());
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  delegate->SetRootKeys(NULL, unprivileged_.Handle());
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PairingRegistry::Pairing unprivileged_pairing =
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      delegate->Load(pairing.client_id());
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(pairing.client_id(), unprivileged_pairing.client_id());
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(pairing.client_name(), unprivileged_pairing.client_name());
121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_EQ(pairing.created_time(), unprivileged_pairing.created_time());
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Verify that the shared secret if not available.
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(unprivileged_pairing.shared_secret().empty());
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Verify that a pairing cannot be saved.
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_FALSE(delegate->Save(pairing));
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace remoting
131