policy_header_service.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/policy_header_service.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/base64.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/json/json_writer.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/values.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_store.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/policy_header_io_helper.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kUserDMTokenKey[] = "user_dmtoken"; 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kUserPolicyTokenKey[] = "user_policy_token"; 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kVerificationKeyHashKey[] = "verification_key_id"; 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace policy { 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PolicyHeaderService::PolicyHeaderService( 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& server_url, 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& verification_key_hash, 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloudPolicyStore* user_policy_store, 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloudPolicyStore* device_policy_store) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : server_url_(server_url), 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verification_key_hash_(verification_key_hash), 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_policy_store_(user_policy_store), 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_policy_store_(device_policy_store) { 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_policy_store_->AddObserver(this); 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (device_policy_store_) 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_policy_store_->AddObserver(this); 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PolicyHeaderService::~PolicyHeaderService() { 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_policy_store_->RemoveObserver(this); 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (device_policy_store_) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) device_policy_store_->RemoveObserver(this); 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_ptr<PolicyHeaderIOHelper> 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PolicyHeaderService::CreatePolicyHeaderIOHelper( 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> task_runner) { 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string initial_header_value = CreateHeaderValue(); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<PolicyHeaderIOHelper> helper = make_scoped_ptr( 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new PolicyHeaderIOHelper(server_url_, initial_header_value, task_runner)); 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) helpers_.push_back(helper.get()); 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return helper.Pass(); 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string PolicyHeaderService::CreateHeaderValue() { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have no user policy or no token, return an empty header. 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!user_policy_store_->has_policy() || 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !user_policy_store_->policy()->has_request_token()) { 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ""; 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Generate a Base64-encoded header of the form: 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // { 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // user_dmtoken: <dm_token> 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // user_policy_token: <policy_token> 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // verification_key_hash: <key_hash> 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // } 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string user_dm_token = user_policy_store_->policy()->request_token(); 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue value; 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) value.SetString(kUserDMTokenKey, user_dm_token); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (user_policy_store_->policy()->has_policy_token()) { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) value.SetString(kUserPolicyTokenKey, 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_policy_store_->policy()->policy_token()); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!verification_key_hash_.empty()) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) value.SetString(kVerificationKeyHashKey, verification_key_hash_); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(atwilson): add user_policy_token once the server starts sending it 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // down (http://crbug.com/326799). 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string json; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::JSONWriter::Write(&value, &json); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!json.empty()); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Base64-encode the result so we can include it in a header. 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string encoded; 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Base64Encode(json, &encoded); 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return encoded; 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PolicyHeaderService::OnStoreLoaded(CloudPolicyStore* store) { 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a PolicyHeaderIOHelper, notify it of the new header value. 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!helpers_.empty()) { 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string new_header = CreateHeaderValue(); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<PolicyHeaderIOHelper*>::const_iterator it = 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) helpers_.begin(); it != helpers_.end(); ++it) { 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*it)->UpdateHeader(new_header); 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PolicyHeaderService::OnStoreError(CloudPolicyStore* store) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Do nothing on errors. 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::vector<PolicyHeaderIOHelper*> PolicyHeaderService::GetHelpersForTest() { 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return helpers_; 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace policy 106