Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc

Issue 2488573003: Expose signing key from cloud policy stores (Closed)
Patch Set: Fix tests Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" 5 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h"
6 6
7 #include <stdint.h>
7 #include <memory> 8 #include <memory>
8 #include <string> 9 #include <string>
9 #include <vector> 10 #include <vector>
10 11
11 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
12 #include "base/macros.h" 13 #include "base/macros.h"
13 #include "base/run_loop.h" 14 #include "base/run_loop.h"
14 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
15 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 16 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
16 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" 17 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
17 #include "chrome/browser/chromeos/settings/install_attributes.h" 18 #include "chrome/browser/chromeos/settings/install_attributes.h"
18 #include "chrome/test/base/scoped_testing_local_state.h" 19 #include "chrome/test/base/scoped_testing_local_state.h"
19 #include "chrome/test/base/testing_browser_process.h" 20 #include "chrome/test/base/testing_browser_process.h"
20 #include "chromeos/cryptohome/cryptohome_util.h" 21 #include "chromeos/cryptohome/cryptohome_util.h"
21 #include "chromeos/dbus/dbus_thread_manager.h" 22 #include "chromeos/dbus/dbus_thread_manager.h"
22 #include "chromeos/dbus/fake_cryptohome_client.h" 23 #include "chromeos/dbus/fake_cryptohome_client.h"
23 #include "components/policy/core/common/cloud/cloud_policy_constants.h" 24 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
24 #include "components/policy/policy_constants.h" 25 #include "components/policy/policy_constants.h"
25 #include "components/policy/proto/device_management_backend.pb.h" 26 #include "components/policy/proto/device_management_backend.pb.h"
26 #include "content/public/test/test_utils.h" 27 #include "content/public/test/test_utils.h"
28 #include "crypto/rsa_private_key.h"
27 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
28 30
29 namespace em = enterprise_management; 31 namespace em = enterprise_management;
30 32
31 namespace policy { 33 namespace policy {
32 34
33 namespace { 35 namespace {
34 36
35 void CopyLockResult(base::RunLoop* loop, 37 void CopyLockResult(base::RunLoop* loop,
36 chromeos::InstallAttributes::LockResult* out, 38 chromeos::InstallAttributes::LockResult* out,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 base::Bind(&CopyLockResult, &loop, &result)); 72 base::Bind(&CopyLockResult, &loop, &result));
71 loop.Run(); 73 loop.Run();
72 ASSERT_EQ(chromeos::InstallAttributes::LOCK_SUCCESS, result); 74 ASSERT_EQ(chromeos::InstallAttributes::LOCK_SUCCESS, result);
73 } 75 }
74 76
75 void ExpectFailure(CloudPolicyStore::Status expected_status) { 77 void ExpectFailure(CloudPolicyStore::Status expected_status) {
76 EXPECT_EQ(expected_status, store_->status()); 78 EXPECT_EQ(expected_status, store_->status());
77 EXPECT_TRUE(store_->is_initialized()); 79 EXPECT_TRUE(store_->is_initialized());
78 EXPECT_FALSE(store_->has_policy()); 80 EXPECT_FALSE(store_->has_policy());
79 EXPECT_FALSE(store_->is_managed()); 81 EXPECT_FALSE(store_->is_managed());
82 EXPECT_EQ(std::string(), store_->owning_domain());
83 EXPECT_EQ(std::string(), store_->public_key());
80 } 84 }
81 85
82 void ExpectSuccess() { 86 void ExpectSuccess() {
83 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 87 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
84 EXPECT_TRUE(store_->is_initialized()); 88 EXPECT_TRUE(store_->is_initialized());
85 EXPECT_TRUE(store_->has_policy()); 89 EXPECT_TRUE(store_->has_policy());
86 EXPECT_TRUE(store_->is_managed()); 90 EXPECT_TRUE(store_->is_managed());
87 EXPECT_TRUE(store_->policy()); 91 EXPECT_TRUE(store_->policy());
88 base::FundamentalValue expected(false); 92 base::FundamentalValue expected(false);
89 EXPECT_TRUE( 93 EXPECT_TRUE(
90 base::Value::Equals(&expected, 94 base::Value::Equals(&expected,
91 store_->policy_map().GetValue( 95 store_->policy_map().GetValue(
92 key::kDeviceMetricsReportingEnabled))); 96 key::kDeviceMetricsReportingEnabled)));
97 EXPECT_EQ(PolicyBuilder::kFakeDomain, store_->owning_domain());
98 EXPECT_NE(std::string(), store_->public_key());
93 } 99 }
94 100
95 void PrepareExistingPolicy() { 101 void PrepareExistingPolicy() {
96 store_->Load(); 102 store_->Load();
97 FlushDeviceSettings(); 103 FlushDeviceSettings();
98 ExpectSuccess(); 104 ExpectSuccess();
99 105
100 device_policy_.UnsetNewSigningKey(); 106 device_policy_.UnsetNewSigningKey();
101 device_policy_.Build(); 107 device_policy_.Build();
102 } 108 }
103 109
104 void PrepareNewSigningKey() { 110 void PrepareNewSigningKey() {
105 device_policy_.SetDefaultNewSigningKey(); 111 device_policy_.SetDefaultNewSigningKey();
106 device_policy_.Build(); 112 device_policy_.Build();
107 owner_key_util_->SetPublicKeyFromPrivateKey( 113 owner_key_util_->SetPublicKeyFromPrivateKey(
108 *device_policy_.GetNewSigningKey()); 114 *device_policy_.GetNewSigningKey());
109 } 115 }
110 116
111 void ResetToNonEnterprise() { 117 void ResetToNonEnterprise() {
112 store_.reset(); 118 store_.reset();
113 chromeos::cryptohome_util::InstallAttributesSet("enterprise.owned", 119 chromeos::cryptohome_util::InstallAttributesSet("enterprise.owned",
114 std::string()); 120 std::string());
115 install_attributes_.reset( 121 install_attributes_.reset(
116 new chromeos::InstallAttributes(fake_cryptohome_client_)); 122 new chromeos::InstallAttributes(fake_cryptohome_client_));
117 store_.reset(new DeviceCloudPolicyStoreChromeOS( 123 store_.reset(new DeviceCloudPolicyStoreChromeOS(
118 &device_settings_service_, install_attributes_.get(), 124 &device_settings_service_, install_attributes_.get(),
119 base::ThreadTaskRunnerHandle::Get())); 125 base::ThreadTaskRunnerHandle::Get()));
120 } 126 }
121 127
128 static std::string ConvertPublicKeyToString(
129 const std::vector<uint8_t>& public_key) {
130 return std::string(reinterpret_cast<const char*>(public_key.data()),
131 public_key.size());
132 }
133
134 std::string GetPolicyPublicKeyAsString() {
emaxx 2016/11/08 20:53:36 I'd like to land a separate CL that would move the
135 std::vector<uint8_t> public_key;
136 EXPECT_TRUE(device_policy_.GetSigningKey()->ExportPublicKey(&public_key));
137 return ConvertPublicKeyToString(public_key);
138 }
139
140 std::string GetPolicyNewPublicKeyAsString() {
141 std::vector<uint8_t> new_public_key;
142 EXPECT_TRUE(
143 device_policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
144 return ConvertPublicKeyToString(new_public_key);
145 }
146
122 ScopedTestingLocalState local_state_; 147 ScopedTestingLocalState local_state_;
123 chromeos::FakeCryptohomeClient* fake_cryptohome_client_; 148 chromeos::FakeCryptohomeClient* fake_cryptohome_client_;
124 std::unique_ptr<chromeos::InstallAttributes> install_attributes_; 149 std::unique_ptr<chromeos::InstallAttributes> install_attributes_;
125 150
126 std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store_; 151 std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store_;
127 152
128 private: 153 private:
129 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyStoreChromeOSTest); 154 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyStoreChromeOSTest);
130 }; 155 };
131 156
(...skipping 15 matching lines...) Expand all
147 ResetToNonEnterprise(); 172 ResetToNonEnterprise();
148 store_->Load(); 173 store_->Load();
149 FlushDeviceSettings(); 174 FlushDeviceSettings();
150 ExpectFailure(CloudPolicyStore::STATUS_BAD_STATE); 175 ExpectFailure(CloudPolicyStore::STATUS_BAD_STATE);
151 } 176 }
152 177
153 TEST_F(DeviceCloudPolicyStoreChromeOSTest, LoadSuccess) { 178 TEST_F(DeviceCloudPolicyStoreChromeOSTest, LoadSuccess) {
154 store_->Load(); 179 store_->Load();
155 FlushDeviceSettings(); 180 FlushDeviceSettings();
156 ExpectSuccess(); 181 ExpectSuccess();
182 EXPECT_EQ(GetPolicyPublicKeyAsString(), store_->public_key());
157 } 183 }
158 184
159 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreSuccess) { 185 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreSuccess) {
160 PrepareExistingPolicy(); 186 PrepareExistingPolicy();
161 store_->Store(device_policy_.policy()); 187 store_->Store(device_policy_.policy());
162 FlushDeviceSettings(); 188 FlushDeviceSettings();
163 ExpectSuccess(); 189 ExpectSuccess();
190 EXPECT_EQ(GetPolicyPublicKeyAsString(), store_->public_key());
164 } 191 }
165 192
166 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreNoSignature) { 193 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreNoSignature) {
167 PrepareExistingPolicy(); 194 PrepareExistingPolicy();
168 device_policy_.policy().clear_policy_data_signature(); 195 device_policy_.policy().clear_policy_data_signature();
169 store_->Store(device_policy_.policy()); 196 store_->Store(device_policy_.policy());
170 FlushDeviceSettings(); 197 FlushDeviceSettings();
171 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 198 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
172 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE, 199 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE,
173 store_->validation_status()); 200 store_->validation_status());
201 EXPECT_EQ(GetPolicyPublicKeyAsString(), store_->public_key());
174 } 202 }
175 203
176 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreBadSignature) { 204 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreBadSignature) {
177 PrepareExistingPolicy(); 205 PrepareExistingPolicy();
178 device_policy_.policy().set_policy_data_signature("invalid"); 206 device_policy_.policy().set_policy_data_signature("invalid");
179 store_->Store(device_policy_.policy()); 207 store_->Store(device_policy_.policy());
180 FlushDeviceSettings(); 208 FlushDeviceSettings();
181 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 209 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
182 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE, 210 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_SIGNATURE,
183 store_->validation_status()); 211 store_->validation_status());
212 EXPECT_EQ(GetPolicyPublicKeyAsString(), store_->public_key());
184 } 213 }
185 214
186 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreKeyRotation) { 215 TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreKeyRotation) {
187 PrepareExistingPolicy(); 216 PrepareExistingPolicy();
188 device_policy_.SetDefaultNewSigningKey(); 217 device_policy_.SetDefaultNewSigningKey();
189 device_policy_.Build(); 218 device_policy_.Build();
190 store_->Store(device_policy_.policy()); 219 store_->Store(device_policy_.policy());
191 content::RunAllBlockingPoolTasksUntilIdle(); 220 content::RunAllBlockingPoolTasksUntilIdle();
192 device_settings_test_helper_.FlushStore(); 221 device_settings_test_helper_.FlushStore();
193 owner_key_util_->SetPublicKeyFromPrivateKey( 222 owner_key_util_->SetPublicKeyFromPrivateKey(
194 *device_policy_.GetNewSigningKey()); 223 *device_policy_.GetNewSigningKey());
195 ReloadDeviceSettings(); 224 ReloadDeviceSettings();
196 ExpectSuccess(); 225 ExpectSuccess();
226 EXPECT_EQ(GetPolicyNewPublicKeyAsString(), store_->public_key());
197 } 227 }
198 228
199 TEST_F(DeviceCloudPolicyStoreChromeOSTest, 229 TEST_F(DeviceCloudPolicyStoreChromeOSTest,
200 StoreKeyRotationVerificationFailure) { 230 StoreKeyRotationVerificationFailure) {
201 PrepareExistingPolicy(); 231 PrepareExistingPolicy();
202 device_policy_.SetDefaultNewSigningKey(); 232 device_policy_.SetDefaultNewSigningKey();
203 device_policy_.Build(); 233 device_policy_.Build();
204 *device_policy_.policy() 234 *device_policy_.policy()
205 .mutable_new_public_key_verification_signature_deprecated() = "garbage"; 235 .mutable_new_public_key_verification_signature_deprecated() = "garbage";
206 store_->Store(device_policy_.policy()); 236 store_->Store(device_policy_.policy());
207 FlushDeviceSettings(); 237 FlushDeviceSettings();
208 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 238 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
209 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE, 239 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE,
210 store_->validation_status()); 240 store_->validation_status());
241 EXPECT_EQ(GetPolicyPublicKeyAsString(), store_->public_key());
211 } 242 }
212 243
213 TEST_F(DeviceCloudPolicyStoreChromeOSTest, 244 TEST_F(DeviceCloudPolicyStoreChromeOSTest,
214 StoreKeyRotationMissingSignatureFailure) { 245 StoreKeyRotationMissingSignatureFailure) {
215 PrepareExistingPolicy(); 246 PrepareExistingPolicy();
216 device_policy_.SetDefaultNewSigningKey(); 247 device_policy_.SetDefaultNewSigningKey();
217 device_policy_.Build(); 248 device_policy_.Build();
218 device_policy_.policy() 249 device_policy_.policy()
219 .clear_new_public_key_verification_signature_deprecated(); 250 .clear_new_public_key_verification_signature_deprecated();
220 store_->Store(device_policy_.policy()); 251 store_->Store(device_policy_.policy());
221 FlushDeviceSettings(); 252 FlushDeviceSettings();
222 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status()); 253 EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
223 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE, 254 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE,
224 store_->validation_status()); 255 store_->validation_status());
256 EXPECT_EQ(GetPolicyPublicKeyAsString(), store_->public_key());
225 } 257 }
226 258
227 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicySuccess) { 259 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicySuccess) {
228 PrepareNewSigningKey(); 260 PrepareNewSigningKey();
229 store_->InstallInitialPolicy(device_policy_.policy()); 261 store_->InstallInitialPolicy(device_policy_.policy());
230 FlushDeviceSettings(); 262 FlushDeviceSettings();
231 ExpectSuccess(); 263 ExpectSuccess();
264 EXPECT_EQ(GetPolicyNewPublicKeyAsString(), store_->public_key());
232 } 265 }
233 266
234 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicyNoSignature) { 267 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicyNoSignature) {
235 PrepareNewSigningKey(); 268 PrepareNewSigningKey();
236 device_policy_.policy().clear_policy_data_signature(); 269 device_policy_.policy().clear_policy_data_signature();
237 store_->InstallInitialPolicy(device_policy_.policy()); 270 store_->InstallInitialPolicy(device_policy_.policy());
238 FlushDeviceSettings(); 271 FlushDeviceSettings();
239 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR); 272 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR);
240 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE, 273 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE,
241 store_->validation_status()); 274 store_->validation_status());
275 EXPECT_EQ(std::string(), store_->public_key());
242 } 276 }
243 277
244 TEST_F(DeviceCloudPolicyStoreChromeOSTest, 278 TEST_F(DeviceCloudPolicyStoreChromeOSTest,
245 InstallInitialPolicyVerificationFailure) { 279 InstallInitialPolicyVerificationFailure) {
246 PrepareNewSigningKey(); 280 PrepareNewSigningKey();
247 *device_policy_.policy() 281 *device_policy_.policy()
248 .mutable_new_public_key_verification_signature_deprecated() = "garbage"; 282 .mutable_new_public_key_verification_signature_deprecated() = "garbage";
249 store_->InstallInitialPolicy(device_policy_.policy()); 283 store_->InstallInitialPolicy(device_policy_.policy());
250 FlushDeviceSettings(); 284 FlushDeviceSettings();
251 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR); 285 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR);
252 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE, 286 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE,
253 store_->validation_status()); 287 store_->validation_status());
288 EXPECT_EQ(std::string(), store_->public_key());
254 } 289 }
255 290
256 TEST_F(DeviceCloudPolicyStoreChromeOSTest, 291 TEST_F(DeviceCloudPolicyStoreChromeOSTest,
257 InstallInitialPolicyMissingSignatureFailure) { 292 InstallInitialPolicyMissingSignatureFailure) {
258 PrepareNewSigningKey(); 293 PrepareNewSigningKey();
259 device_policy_.policy() 294 device_policy_.policy()
260 .clear_new_public_key_verification_signature_deprecated(); 295 .clear_new_public_key_verification_signature_deprecated();
261 store_->InstallInitialPolicy(device_policy_.policy()); 296 store_->InstallInitialPolicy(device_policy_.policy());
262 FlushDeviceSettings(); 297 FlushDeviceSettings();
263 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR); 298 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR);
264 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE, 299 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE,
265 store_->validation_status()); 300 store_->validation_status());
301 EXPECT_EQ(std::string(), store_->public_key());
266 } 302 }
267 303
268 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicyNoKey) { 304 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicyNoKey) {
269 PrepareNewSigningKey(); 305 PrepareNewSigningKey();
270 device_policy_.policy().clear_new_public_key(); 306 device_policy_.policy().clear_new_public_key();
271 store_->InstallInitialPolicy(device_policy_.policy()); 307 store_->InstallInitialPolicy(device_policy_.policy());
272 FlushDeviceSettings(); 308 FlushDeviceSettings();
273 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR); 309 ExpectFailure(CloudPolicyStore::STATUS_VALIDATION_ERROR);
274 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE, 310 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE,
275 store_->validation_status()); 311 store_->validation_status());
312 EXPECT_EQ(std::string(), store_->public_key());
276 } 313 }
277 314
278 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicyNotEnterprise) { 315 TEST_F(DeviceCloudPolicyStoreChromeOSTest, InstallInitialPolicyNotEnterprise) {
279 PrepareNewSigningKey(); 316 PrepareNewSigningKey();
280 ResetToNonEnterprise(); 317 ResetToNonEnterprise();
281 store_->InstallInitialPolicy(device_policy_.policy()); 318 store_->InstallInitialPolicy(device_policy_.policy());
282 FlushDeviceSettings(); 319 FlushDeviceSettings();
283 ExpectFailure(CloudPolicyStore::STATUS_BAD_STATE); 320 ExpectFailure(CloudPolicyStore::STATUS_BAD_STATE);
321 EXPECT_EQ(std::string(), store_->public_key());
284 } 322 }
285 323
286 } // namespace policy 324 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698