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 // Tests are an unofficial build, so only Chromium will be used. | |
Lei Zhang
2016/07/20 01:08:26
Umm, I think there exists an internal waterfall th
cfroussios
2016/07/20 15:22:46
Done. I added a comment about why I'm not pulling
| |
117 const std::string expected_folder_name_ = "Chromium Keys"; | |
118 const std::string expected_entry_name_ = "Chromium Safe Storage"; | |
119 | |
120 private: | |
121 DISALLOW_COPY_AND_ASSIGN(KeyStorageKWalletTest); | |
122 }; | |
123 | |
124 TEST_F(KeyStorageKWalletTest, InitializeFolder) { | |
125 SuccessfulInit(); | |
126 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
127 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
128 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, expected_folder_name_, _, _)) | |
129 .WillOnce(DoAll(SetArgPointee<3>(false), Return(SUCCESS))); | |
130 EXPECT_CALL(*kwallet_dbus_mock_, | |
131 CreateFolder(123, expected_folder_name_, _, _)) | |
132 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
133 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, expected_folder_name_, | |
134 expected_entry_name_, _, _)) | |
135 .WillOnce(DoAll(SetArgPointee<4>("butter"), Return(SUCCESS))); | |
136 | |
137 std::string password = key_storage_kwallet_.GetKey(); | |
138 EXPECT_EQ("butter", password); | |
Lei Zhang
2016/07/20 01:08:26
Can we do EXPECT_STREQ(), and just drop |password|
cfroussios
2016/07/20 15:22:46
Butter from peanuts.
GetKey() doesn't return a C
| |
139 } | |
140 | |
141 TEST_F(KeyStorageKWalletTest, ExistingPassword) { | |
142 SuccessfulInit(); | |
143 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
144 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
145 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, expected_folder_name_, _, _)) | |
146 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
147 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, expected_folder_name_, | |
148 expected_entry_name_, _, _)) | |
149 .WillOnce(DoAll(SetArgPointee<4>("butter"), Return(SUCCESS))); | |
150 | |
151 std::string password = key_storage_kwallet_.GetKey(); | |
152 EXPECT_EQ("butter", password); | |
153 } | |
154 | |
155 TEST_F(KeyStorageKWalletTest, GenerateNewPassword) { | |
156 SuccessfulInit(); | |
157 std::string generated_password; | |
158 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
159 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
160 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, expected_folder_name_, _, _)) | |
161 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
162 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, expected_folder_name_, | |
163 expected_entry_name_, _, _)) | |
164 .WillOnce(DoAll(SetArgPointee<4>(""), Return(SUCCESS))); | |
165 EXPECT_CALL(*kwallet_dbus_mock_, WritePassword(123, expected_folder_name_, | |
166 expected_entry_name_, _, _, _)) | |
167 .WillOnce(DoAll(SaveArg<3>(&generated_password), SetArgPointee<5>(true), | |
168 Return(SUCCESS))); | |
169 | |
170 std::string password = key_storage_kwallet_.GetKey(); | |
171 EXPECT_EQ(generated_password, password); | |
172 } | |
173 | |
174 TEST_F(KeyStorageKWalletTest, InitKWalletNotEnabled) { | |
175 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
176 .WillOnce(DoAll(SetArgPointee<0>(false), Return(SUCCESS))); | |
177 | |
178 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
179 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
180 } | |
181 | |
182 TEST_F(KeyStorageKWalletTest, InitCannotStart) { | |
183 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
184 .WillOnce(Return(CANNOT_CONTACT)); | |
185 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(false)); | |
186 | |
187 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
188 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
189 } | |
190 | |
191 TEST_F(KeyStorageKWalletTest, InitFailTwice) { | |
192 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
193 .WillOnce(Return(CANNOT_CONTACT)) | |
194 .WillOnce(Return(CANNOT_CONTACT)); | |
195 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(true)); | |
196 | |
197 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
198 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
199 } | |
200 | |
201 TEST_F(KeyStorageKWalletTest, InitTryTwiceAndFail) { | |
202 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
203 .WillOnce(Return(CANNOT_CONTACT)) | |
204 .WillOnce(DoAll(SetArgPointee<0>(true), Return(SUCCESS))); | |
205 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(true)); | |
206 EXPECT_CALL(*kwallet_dbus_mock_, NetworkWallet(_)) | |
207 .WillOnce(Return(CANNOT_CONTACT)); | |
208 | |
209 EXPECT_FALSE(key_storage_kwallet_.InitWithKWalletDBus( | |
210 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
211 } | |
212 | |
213 TEST_F(KeyStorageKWalletTest, InitTryTwiceAndSuccess) { | |
214 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
215 .WillOnce(Return(CANNOT_CONTACT)) | |
216 .WillOnce(DoAll(SetArgPointee<0>(true), Return(SUCCESS))); | |
217 EXPECT_CALL(*kwallet_dbus_mock_, StartKWalletd()).WillOnce(Return(true)); | |
218 EXPECT_CALL(*kwallet_dbus_mock_, NetworkWallet(_)) | |
219 .WillOnce(DoAll(SetArgPointee<0>(wallet_name_), Return(SUCCESS))); | |
220 | |
221 EXPECT_TRUE(key_storage_kwallet_.InitWithKWalletDBus( | |
222 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
223 } | |
224 | |
225 // Tests for a dbus connection that fails after initialization. | |
226 // Any error is expected to return an empty password. | |
227 class KeyStorageKWalletFailuresTest | |
228 : public testing::TestWithParam<KWalletDBus::Error> { | |
229 public: | |
230 KeyStorageKWalletFailuresTest() | |
231 : key_storage_kwallet_(kDesktopEnv, "test-app") {} | |
232 | |
233 void SetUp() override { | |
234 // |key_storage_kwallet_| will take ownership of |kwallet_dbus_mock_|. | |
235 kwallet_dbus_mock_ = new StrictMock<MockKWalletDBus>(); | |
236 | |
237 // Successful initialization. | |
238 EXPECT_CALL(*kwallet_dbus_mock_, IsEnabled(_)) | |
239 .WillOnce(DoAll(SetArgPointee<0>(true), Return(SUCCESS))); | |
240 EXPECT_CALL(*kwallet_dbus_mock_, NetworkWallet(_)) | |
241 .WillOnce( | |
242 DoAll(SetArgPointee<0>(std::string("mollet")), Return(SUCCESS))); | |
243 | |
244 EXPECT_TRUE(key_storage_kwallet_.InitWithKWalletDBus( | |
245 std::unique_ptr<MockKWalletDBus>(kwallet_dbus_mock_))); | |
246 | |
247 // Calls from |key_storage_kwallet_|'s destructor. | |
248 EXPECT_CALL(*kwallet_dbus_mock_, Close(_, false, _, _)) | |
249 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
250 EXPECT_CALL(*kwallet_dbus_mock_->GetSessionBus(), ShutdownAndBlock()) | |
251 .Times(1); | |
252 } | |
253 | |
254 protected: | |
255 StrictMock<MockKWalletDBus>* kwallet_dbus_mock_; | |
256 KeyStorageKWallet key_storage_kwallet_; | |
257 const std::string wallet_name_ = "mollet"; | |
258 | |
259 private: | |
260 DISALLOW_COPY_AND_ASSIGN(KeyStorageKWalletFailuresTest); | |
261 }; | |
262 | |
263 INSTANTIATE_TEST_CASE_P(, | |
264 KeyStorageKWalletFailuresTest, | |
265 ::testing::Values(CANNOT_READ, CANNOT_CONTACT)); | |
266 | |
267 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureOpen) { | |
268 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)).WillOnce(Return(GetParam())); | |
269 | |
270 std::string password = key_storage_kwallet_.GetKey(); | |
271 EXPECT_EQ("", password); | |
272 } | |
273 | |
274 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureHasFolder) { | |
275 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
276 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
277 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, _, _, _)) | |
278 .WillOnce(Return(GetParam())); | |
279 | |
280 std::string password = key_storage_kwallet_.GetKey(); | |
281 EXPECT_EQ("", password); | |
282 } | |
283 | |
284 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureCreateFolder) { | |
285 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
286 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
287 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, _, _, _)) | |
288 .WillOnce(DoAll(SetArgPointee<3>(false), Return(SUCCESS))); | |
289 EXPECT_CALL(*kwallet_dbus_mock_, CreateFolder(123, _, _, _)) | |
290 .WillOnce(Return(GetParam())); | |
291 | |
292 std::string password = key_storage_kwallet_.GetKey(); | |
293 EXPECT_EQ("", password); | |
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 std::string password = key_storage_kwallet_.GetKey(); | |
305 EXPECT_EQ("", password); | |
306 } | |
307 | |
308 TEST_P(KeyStorageKWalletFailuresTest, PostInitFailureWritePassword) { | |
309 EXPECT_CALL(*kwallet_dbus_mock_, Open(_, _, _)) | |
310 .WillOnce(DoAll(SetArgPointee<2>(123), Return(SUCCESS))); | |
311 EXPECT_CALL(*kwallet_dbus_mock_, HasFolder(123, _, _, _)) | |
312 .WillOnce(DoAll(SetArgPointee<3>(true), Return(SUCCESS))); | |
313 EXPECT_CALL(*kwallet_dbus_mock_, ReadPassword(123, _, _, _, _)) | |
314 .WillOnce(DoAll(SetArgPointee<4>(""), Return(SUCCESS))); | |
315 EXPECT_CALL(*kwallet_dbus_mock_, WritePassword(123, _, _, _, _, _)) | |
316 .WillOnce(Return(GetParam())); | |
317 | |
318 std::string password = key_storage_kwallet_.GetKey(); | |
319 EXPECT_EQ("", password); | |
320 } | |
321 | |
322 } // namespace | |
OLD | NEW |