• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "chrome/browser/transport_security_persister.h"
6 
7 #include "base/file_path.h"
8 #include "base/file_util.h"
9 #include "base/message_loop.h"
10 #include "base/path_service.h"
11 #include "chrome/common/chrome_paths.h"
12 #include "content/browser/browser_thread.h"
13 #include "net/base/transport_security_state.h"
14 
TransportSecurityPersister(bool readonly)15 TransportSecurityPersister::TransportSecurityPersister(bool readonly)
16   : ALLOW_THIS_IN_INITIALIZER_LIST(save_coalescer_(this)),
17     readonly_(readonly) {
18 }
19 
~TransportSecurityPersister()20 TransportSecurityPersister::~TransportSecurityPersister() {
21   transport_security_state_->SetDelegate(NULL);
22 }
23 
Initialize(net::TransportSecurityState * state,const FilePath & profile_path)24 void TransportSecurityPersister::Initialize(
25     net::TransportSecurityState* state, const FilePath& profile_path) {
26   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
27   transport_security_state_ = state;
28   state_file_ =
29       profile_path.Append(FILE_PATH_LITERAL("TransportSecurity"));
30   state->SetDelegate(this);
31 
32   Task* task = NewRunnableMethod(this,
33       &TransportSecurityPersister::Load);
34   BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, task, 1000);
35 }
36 
Load()37 void TransportSecurityPersister::Load() {
38   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
39 
40   std::string state;
41   if (!file_util::ReadFileToString(state_file_, &state))
42     return;
43 
44   BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
45       NewRunnableMethod(this,
46                         &TransportSecurityPersister::CompleteLoad,
47                         state));
48 }
49 
CompleteLoad(const std::string & state)50 void TransportSecurityPersister::CompleteLoad(const std::string& state) {
51   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
52 
53   bool dirty = false;
54   if (!transport_security_state_->LoadEntries(state, &dirty)) {
55     LOG(ERROR) << "Failed to deserialize state: " << state;
56     return;
57   }
58   if (dirty)
59     StateIsDirty(transport_security_state_);
60 }
61 
StateIsDirty(net::TransportSecurityState * state)62 void TransportSecurityPersister::StateIsDirty(
63     net::TransportSecurityState* state) {
64   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
65   DCHECK(state == transport_security_state_);
66 
67   if (readonly_)
68     return;
69 
70   if (!save_coalescer_.empty())
71     return;
72 
73   Task* task = save_coalescer_.NewRunnableMethod(
74       &TransportSecurityPersister::Save);
75   MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 1000);
76 }
77 
Save()78 void TransportSecurityPersister::Save() {
79   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
80 
81   std::string state;
82   if (!transport_security_state_->Serialise(&state))
83     return;
84 
85   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
86       NewRunnableMethod(this,
87                         &TransportSecurityPersister::CompleteSave,
88                         state));
89 }
90 
CompleteSave(const std::string & state)91 void TransportSecurityPersister::CompleteSave(const std::string& state) {
92   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
93   DCHECK(!readonly_);
94 
95   file_util::WriteFile(state_file_, state.data(), state.size());
96 }
97