OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "components/os_crypt/key_storage_kwallet.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/nix/xdg_util.h" | |
9 #include "dbus/message.h" | |
10 #include "dbus/mock_bus.h" | |
11 #include "dbus/mock_object_proxy.h" | |
12 #include "dbus/object_path.h" | |
13 #include "dbus/object_proxy.h" | |
14 #include "testing/gmock/include/gmock/gmock.h" | |
15 #include "testing/gtest/include/gtest/gtest.h" | |
16 | |
17 namespace { | |
18 | |
19 using testing::_; | |
20 using testing::DoAll; | |
21 using testing::Return; | |
22 using testing::SaveArg; | |
23 using testing::SetArgPointee; | |
24 using testing::StrictMock; | |
25 | |
26 constexpr KWalletDBus::Error SUCCESS = KWalletDBus::Error::SUCCESS; | |
27 constexpr KWalletDBus::Error CANNOT_READ = KWalletDBus::Error::CANNOT_READ; | |
28 constexpr KWalletDBus::Error CANNOT_CONTACT = | |
29 KWalletDBus::Error::CANNOT_CONTACT; | |
30 | |
31 // Environment-specific behavior is handled and tested with KWalletDBus, not | |
32 // here, but we still need a value to instantiate. | |
33 const base::nix::DesktopEnvironment kDesktopEnv = | |
34 base::nix::DesktopEnvironment::DESKTOP_ENVIRONMENT_KDE5; | |
35 | |
36 class MockKWalletDBus : public KWalletDBus { | |
37 public: | |
38 MockKWalletDBus() : KWalletDBus(kDesktopEnv) { | |
39 // On destruction, GetSessionBus() is called to get the bus and shut it | |
40 // down. Here we create a mock to be returned by GetSessionBus(). | |
41 mock_session_bus_ = new dbus::MockBus(dbus::Bus::Options()); | |
42 } | |
43 | |
44 dbus::MockBus* GetSessionBus() override { return mock_session_bus_.get(); } | |
45 | |
46 MOCK_METHOD0(StartKWalletd, bool()); | |
47 | |
48 MOCK_METHOD1(IsEnabled, KWalletDBus::Error(bool*)); | |
49 | |
50 MOCK_METHOD1(NetworkWallet, KWalletDBus::Error(std::string*)); | |
51 | |
52 MOCK_METHOD3(Open, | |
53 KWalletDBus::Error(const std::string&, | |
54 const std::string&, | |
55 int*)); | |
56 | |
57 MOCK_METHOD4( | |
58 HasFolder, | |
59 KWalletDBus::Error(int, const std::string&, const std::string&, bool*)); | |
60 | |
61 MOCK_METHOD4( | |
62 CreateFolder, | |
63 KWalletDBus::Error(int, const std::string&, const std::string&, bool*)); | |
64 | |
65 MOCK_METHOD5(ReadPassword, | |
66 KWalletDBus::Error(int, | |
67 const std::string&, | |
68 const std::string&, | |
69 const std::string&, | |
70 std::string*)); | |
71 | |
72 MOCK_METHOD6(WritePassword, | |
73 KWalletDBus::Error(int, | |
74 const std::string&, | |
75 const std::string&, | |
76 const std::string&, | |
77 const std::string&, | |
78 bool*)); | |
79 | |
80 MOCK_METHOD4(Close, KWalletDBus::Error(int, bool, const std::string&, bool*)); | |
81 | |
82 private: | |
83 scoped_refptr<dbus::MockBus> mock_session_bus_; | |
84 }; | |
85 | |
86 class KeyStorageKWalletTest : public testing::Test { | |
87 public: | |
88 KeyStorageKWalletTest() : key_storage_kwallet_(kDesktopEnv, "test-app") {} | |
89 | |
90 void SetUp() override { | |
91 kwallet_dbus_mock_ = new StrictMock<MockKWalletDBus>(); | |
92 | |
93 // Calls from |key_storage_kwallet_|'s destructor | |
94 EXPECT_CALL(*kwallet_dbus_mock_, Close(_, false, _, _)) | |
95 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
96 EXPECT_CALL(*kwallet_dbus_mock_->GetSessionBus(), ShutdownAndBlock()) | |
97 .Times(1); | |
98 } | |
99 | |
100 void SuccessfulInit() { | |
101 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
102 .WillOnce(DoAll(SetArgPointee<0>(true), Return(SUCCESS))); | |
103 EXPECT_CALL(*kwallet_dbus_mock_, NetworkWallet(_)) | |
104 .WillOnce( | |
105 DoAll(SetArgPointee<0>(std::string("mollet")), Return(SUCCESS))); | |
106 | |
107 EXPECT_TRUE(key_storage_kwallet_.InitWithKWalletDBus( | |
108 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
109 } | |
110 | |
111 protected: | |
112 StrictMock<MockKWalletDBus>* kwallet_dbus_mock_; | |
113 KeyStorageKWallet key_storage_kwallet_; | |
114 const std::string wallet_name_ = "mollet"; | |
115 | |
116 // These names are not allowed to change in prod, unless we intentionally | |
117 // migrate. | |
118 #if defined(OFFICIAL_BUILD) | |
119 const std::string expected_folder_name_ = "Chrome Keys"; | |
Lei Zhang
2016/07/20 19:15:07
Do these have to be class members? Can this be con
cfroussios
2016/07/21 11:49:46
Done.
| |
120 const std::string expected_entry_name_ = "Chrome Safe Storage"; | |
121 #else | |
122 const std::string expected_folder_name_ = "Chromium Keys"; | |
123 const std::string expected_entry_name_ = "Chromium Safe Storage"; | |
124 #endif | |
125 | |
126 private: | |
127 DISALLOW_COPY_AND_ASSIGN(KeyStorageKWalletTest); | |
128 }; | |
129 | |
130 TEST_F(KeyStorageKWalletTest, InitializeFolder) { | |
131 SuccessfulInit(); | |
132 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
133 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
134 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, expected_folder_name_, _, _)) | |
135 .WillOnce(DoAll(SetArgPointee<3>(false), Return(SUCCESS))); | |
136 EXPECT_CALL(*kwallet_dbus_mock_, | |
137 CreateFolder(123, expected_folder_name_, _, _)) | |
138 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
139 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, expected_folder_name_, | |
140 expected_entry_name_, _, _)) | |
141 .WillOnce(DoAll(SetArgPointee<4>("butter"), Return(SUCCESS))); | |
142 | |
143 EXPECT_EQ("butter", key_storage_kwallet_.GetKey()); | |
144 } | |
145 | |
146 TEST_F(KeyStorageKWalletTest, ExistingPassword) { | |
147 SuccessfulInit(); | |
148 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
149 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
150 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, expected_folder_name_, _, _)) | |
151 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
152 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, expected_folder_name_, | |
153 expected_entry_name_, _, _)) | |
154 .WillOnce(DoAll(SetArgPointee<4>("butter"), Return(SUCCESS))); | |
155 | |
156 EXPECT_EQ("butter", key_storage_kwallet_.GetKey()); | |
157 } | |
158 | |
159 TEST_F(KeyStorageKWalletTest, GenerateNewPassword) { | |
160 SuccessfulInit(); | |
161 std::string generated_password; | |
162 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
163 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
164 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, expected_folder_name_, _, _)) | |
165 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
166 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, expected_folder_name_, | |
167 expected_entry_name_, _, _)) | |
168 .WillOnce(DoAll(SetArgPointee<4>(""), Return(SUCCESS))); | |
169 EXPECT_CALL(*kwallet_dbus_mock_, WritePassword(123, expected_folder_name_, | |
170 expected_entry_name_, _, _, _)) | |
171 .WillOnce(DoAll(SaveArg<3>(&generated_password), SetArgPointee<5>(true), | |
172 Return(SUCCESS))); | |
173 | |
174 EXPECT_EQ(generated_password, key_storage_kwallet_.GetKey()); | |
175 } | |
176 | |
177 TEST_F(KeyStorageKWalletTest, InitKWalletNotEnabled) { | |
178 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
179 .WillOnce(DoAll(SetArgPointee<0>(false), Return(SUCCESS))); | |
180 | |
181 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
182 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
183 } | |
184 | |
185 TEST_F(KeyStorageKWalletTest, InitCannotStart) { | |
186 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
187 .WillOnce(Return(CANNOT_CONTACT)); | |
188 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(false)); | |
189 | |
190 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
191 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
192 } | |
193 | |
194 TEST_F(KeyStorageKWalletTest, InitFailTwice) { | |
195 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
196 .WillOnce(Return(CANNOT_CONTACT)) | |
197 .WillOnce(Return(CANNOT_CONTACT)); | |
198 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(true)); | |
199 | |
200 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
201 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
202 } | |
203 | |
204 TEST_F(KeyStorageKWalletTest, InitTryTwiceAndFail) { | |
205 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
206 .WillOnce(Return(CANNOT_CONTACT)) | |
207 .WillOnce(DoAll(SetArgPointee<0>(true), Return(SUCCESS))); | |
208 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(true)); | |
209 EXPECT_CALL(*kwallet_dbus_mock_, NetworkWallet(_)) | |
210 .WillOnce(Return(CANNOT_CONTACT)); | |
211 | |
212 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
213 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
214 } | |
215 | |
216 TEST_F(KeyStorageKWalletTest, InitTryTwiceAndSuccess) { | |
217 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
218 .WillOnce(Return(CANNOT_CONTACT)) | |
219 .WillOnce(DoAll(SetArgPointee<0>(true), Return(SUCCESS))); | |
220 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(true)); | |
221 EXPECT_CALL(*kwallet_dbus_mock_, NetworkWallet(_)) | |
222 .WillOnce(DoAll(SetArgPointee<0>(wallet_name_), Return(SUCCESS))); | |
223 | |
224 EXPECT_TRUE(key_storage_kwallet_.InitWithKWalletDBus( | |
225 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
226 } | |
227 | |
228 // Tests for a dbus connection that fails after initialization. | |
229 // Any error is expected to return an empty password. | |
230 class KeyStorageKWalletFailuresTest | |
231 : public testing::TestWithParam<KWalletDBus::Error> { | |
232 public: | |
233 KeyStorageKWalletFailuresTest() | |
234 : key_storage_kwallet_(kDesktopEnv, "test-app") {} | |
235 | |
236 void SetUp() override { | |
237 // |key_storage_kwallet_| will take ownership of |kwallet_dbus_mock_|. | |
238 kwallet_dbus_mock_ = new StrictMock<MockKWalletDBus>(); | |
239 | |
240 // Successful initialization. | |
241 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
242 .WillOnce(DoAll(SetArgPointee<0>(true), Return(SUCCESS))); | |
243 EXPECT_CALL(*kwallet_dbus_mock_, NetworkWallet(_)) | |
244 .WillOnce( | |
245 DoAll(SetArgPointee<0>(std::string("mollet")), Return(SUCCESS))); | |
246 | |
247 EXPECT_TRUE(key_storage_kwallet_.InitWithKWalletDBus( | |
248 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
249 | |
250 // Calls from |key_storage_kwallet_|'s destructor. | |
251 EXPECT_CALL(*kwallet_dbus_mock_, Close(_, false, _, _)) | |
252 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
253 EXPECT_CALL(*kwallet_dbus_mock_->GetSessionBus(), ShutdownAndBlock()) | |
254 .Times(1); | |
255 } | |
256 | |
257 protected: | |
258 StrictMock<MockKWalletDBus>* kwallet_dbus_mock_; | |
259 KeyStorageKWallet key_storage_kwallet_; | |
260 const std::string wallet_name_ = "mollet"; | |
261 | |
262 private: | |
263 DISALLOW_COPY_AND_ASSIGN(KeyStorageKWalletFailuresTest); | |
264 }; | |
265 | |
266 INSTANTIATE_TEST_CASE_P(, | |
267 KeyStorageKWalletFailuresTest, | |
268 ::testing::Values(CANNOT_READ, CANNOT_CONTACT)); | |
269 | |
270 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureOpen) { | |
271 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)).WillOnce(Return(GetParam())); | |
272 | |
273 EXPECT_EQ("", key_storage_kwallet_.GetKey()); | |
274 } | |
275 | |
276 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureHasFolder) { | |
277 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
278 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
279 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, _, _, _)) | |
280 .WillOnce(Return(GetParam())); | |
281 | |
282 EXPECT_EQ("", key_storage_kwallet_.GetKey()); | |
283 } | |
284 | |
285 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureCreateFolder) { | |
286 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
287 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
288 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, _, _, _)) | |
289 .WillOnce(DoAll(SetArgPointee<3>(false), Return(SUCCESS))); | |
290 EXPECT_CALL(*kwallet_dbus_mock_, CreateFolder(123, _, _, _)) | |
291 .WillOnce(Return(GetParam())); | |
292 | |
293 EXPECT_EQ("", key_storage_kwallet_.GetKey()); | |
294 } | |
295 | |
296 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureReadPassword) { | |
297 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
298 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
299 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, _, _, _)) | |
300 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
301 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, _, _, _, _)) | |
302 .WillOnce(Return(GetParam())); | |
303 | |
304 EXPECT_EQ("", key_storage_kwallet_.GetKey()); | |
305 } | |
306 | |
307 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureWritePassword) { | |
308 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
309 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
310 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, _, _, _)) | |
311 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
312 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, _, _, _, _)) | |
313 .WillOnce(DoAll(SetArgPointee<4>(""), Return(SUCCESS))); | |
314 EXPECT_CALL(*kwallet_dbus_mock_, WritePassword(123, _, _, _, _, _)) | |
315 .WillOnce(Return(GetParam())); | |
316 | |
317 EXPECT_EQ("", key_storage_kwallet_.GetKey()); | |
318 } | |
319 | |
320 } // namespace | |
OLD | NEW |