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

Side by Side Diff: remoting/host/linux/certificate_watcher.cc

Issue 1838313002: Restart the host when the third party auth certificate changes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Reviewer's fb; fixed memory leak Created 4 years, 8 months 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
(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 "remoting/host/linux/certificate_watcher.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h"
Sergey Ulanov 2016/04/05 21:12:56 Don't need this include
Yuwei 2016/04/05 22:18:55 Done.
12 #include "base/path_service.h"
13 #include "base/thread_task_runner_handle.h"
14
15 namespace remoting {
16
17 // Delay time to restart the host when a change of certificate is detected.
18 // This is to avoid repeating restarts when continuous writes to the database
19 // occur.
20 const int kRestartDelayInSecond = 2;
21
22 // Full Path: $HOME/.pki/nssdb
23 const char kCertDirectoryPath[] = ".pki/nssdb";
24
25 CertificateWatcher::CertificateWatcher(
26 const base::Closure& restart_action,
27 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
28 : restart_action_(restart_action),
29 caller_task_runner_(base::ThreadTaskRunnerHandle::Get()),
30 io_task_runner_(io_task_runner),
31 delay_(base::TimeDelta::FromSeconds(kRestartDelayInSecond)) {
32 if (!base::PathService::Get(base::DIR_HOME, &cert_watch_path_)) {
33 LOG(FATAL) << "Failed to get path of the home directory.";
34 }
35 cert_watch_path_ = cert_watch_path_.AppendASCII(kCertDirectoryPath);
36 }
37
38 CertificateWatcher::~CertificateWatcher() {
39 Stop();
40 }
41
42 bool CertificateWatcher::Start() {
Sergey Ulanov 2016/04/05 21:12:55 No longer need to return bool, as it cannot fail a
Yuwei 2016/04/05 22:18:55 Done.
43 DCHECK(caller_task_runner_->BelongsToCurrentThread());
44 DCHECK(!cert_watch_path_.empty());
45
46 file_watcher_.reset(new base::FilePathWatcher());
47 io_task_runner_->PostTask(
48 FROM_HERE,
49 base::Bind(base::IgnoreResult(&base::FilePathWatcher::Watch),
50 base::Unretained(file_watcher_.get()), cert_watch_path_, true,
51 base::Bind(&CertificateWatcher::OnCertDirectoryChanged,
52 caller_task_runner_, this->AsWeakPtr())));
53 restart_timer_.reset(new base::DelayTimer(FROM_HERE, delay_, this,
54 &CertificateWatcher::OnTimer));
55
56 VLOG(1) << "Started watching certificate changes.";
57 return true;
58 }
59
60 void CertificateWatcher::Stop() {
61 DCHECK(caller_task_runner_->BelongsToCurrentThread());
62
63 if (!is_started()) {
64 return;
65 }
66 if (monitor_) {
67 monitor_->RemoveStatusObserver(this);
68 }
69 io_task_runner_->DeleteSoon(FROM_HERE, file_watcher_.release());
70 restart_timer_.reset();
71
72 VLOG(1) << "Stopped watching certificate changes.";
73 }
74
75 void CertificateWatcher::SetMonitor(base::WeakPtr<HostStatusMonitor> monitor) {
76 DCHECK(is_started());
77 if (monitor_) {
78 monitor_->RemoveStatusObserver(this);
79 }
80 monitor->AddStatusObserver(this);
81 monitor_ = monitor;
82 }
83
84 void CertificateWatcher::OnClientConnected(const std::string& jid) {
85 DCHECK(is_started());
86 DCHECK(caller_task_runner_->BelongsToCurrentThread());
87 inhibit_mode_ = true;
88 }
89
90 void CertificateWatcher::OnClientDisconnected(const std::string& jid) {
91 DCHECK(is_started());
92 DCHECK(caller_task_runner_->BelongsToCurrentThread());
93 inhibit_mode_ = false;
94 if (restart_pending_) {
95 restart_pending_ = false;
96 restart_action_.Run();
97 }
98 }
99
100 void CertificateWatcher::SetDelayForTests(const base::TimeDelta& delay) {
101 DCHECK(!is_started());
102 delay_ = delay;
103 }
104
105 void CertificateWatcher::SetWatchPathForTests(
106 const base::FilePath& watch_path) {
107 DCHECK(!is_started());
108 cert_watch_path_ = watch_path;
109 }
110
111 bool CertificateWatcher::is_started() const {
112 return file_watcher_ != nullptr;
113 }
114
115 // static
116 void CertificateWatcher::OnCertDirectoryChanged(
117 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
118 base::WeakPtr<CertificateWatcher> watcher_,
119 const base::FilePath& path,
120 bool error) {
121 network_task_runner->PostTask(
122 FROM_HERE,
123 base::Bind(&CertificateWatcher::DirectoryChanged, watcher_, path, error));
124 }
125
126 void CertificateWatcher::DirectoryChanged(const base::FilePath& path,
127 bool error) {
128 DCHECK(caller_task_runner_->BelongsToCurrentThread());
129
130 if (error || path != cert_watch_path_) {
Sergey Ulanov 2016/04/05 21:12:55 The watcher watches a directory, but here |path| m
Yuwei 2016/04/05 21:27:40 Looks like |path| will never point to something ot
131 LOG(WARNING) << "Unexpected file update callback. "
132 << "Path: " << path.MaybeAsASCII() << "; "
133 << "Error: " << error;
134 return;
135 }
136
137 restart_timer_->Reset();
138 }
139
140 void CertificateWatcher::OnTimer() {
141 DCHECK(caller_task_runner_->BelongsToCurrentThread());
142
143 if (inhibit_mode_) {
144 restart_pending_ = true;
145 return;
146 }
147
148 VLOG(1) << "Certificate was updated. Calling restart...";
149 restart_action_.Run();
150 }
151
152 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698