Linux: remove GLIBC_2.9 as a dependency
[chromium-blink-merge.git] / remoting / host / host_status_sender.cc
blob667c1075790a0a4055a3ff877ae671a387ce91b3
1 // Copyright 2013 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.
5 #include "remoting/host/host_status_sender.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/stringize_macros.h"
9 #include "base/time/time.h"
10 #include "remoting/base/constants.h"
11 #include "remoting/base/logging.h"
12 #include "remoting/host/server_log_entry_host.h"
13 #include "remoting/signaling/iq_sender.h"
14 #include "remoting/signaling/server_log_entry.h"
15 #include "remoting/signaling/signal_strategy.h"
16 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
17 #include "third_party/webrtc/libjingle/xmpp/constants.h"
19 using buzz::QName;
20 using buzz::XmlElement;
22 namespace remoting {
24 namespace {
26 const char kHostStatusTag[] = "host-status";
27 const char kHostIdAttr[] = "hostid";
28 const char kExitCodeAttr[] = "exit-code";
29 const char kHostVersionTag[] = "host-version";
30 const char kSignatureTag[] = "signature";
31 const char kStatusAttr[] = "status";
32 const char kSignatureTimeAttr[] = "time";
34 } // namespace
36 const char* const HostStatusSender::host_status_strings_[] =
37 {"OFFLINE", "ONLINE"};
39 HostStatusSender::HostStatusSender(
40 const std::string& host_id,
41 SignalStrategy* signal_strategy,
42 scoped_refptr<RsaKeyPair> key_pair,
43 const std::string& directory_bot_jid)
44 : host_id_(host_id),
45 signal_strategy_(signal_strategy),
46 key_pair_(key_pair),
47 directory_bot_jid_(directory_bot_jid) {
48 DCHECK(signal_strategy_);
49 DCHECK(key_pair_.get());
51 signal_strategy_->AddListener(this);
54 HostStatusSender::~HostStatusSender() {
55 signal_strategy_->RemoveListener(this);
58 void HostStatusSender::OnSignalStrategyStateChange(
59 SignalStrategy::State state) {
60 if (state == SignalStrategy::CONNECTED)
61 iq_sender_.reset(new IqSender(signal_strategy_));
62 else if (state == SignalStrategy::DISCONNECTED)
63 iq_sender_.reset();
66 bool HostStatusSender::OnSignalStrategyIncomingStanza(
67 const XmlElement* stanza) {
68 return false;
71 void HostStatusSender::SendOfflineStatus(HostExitCodes exit_code) {
72 SendHostStatus(OFFLINE, exit_code);
75 void HostStatusSender::SendOnlineStatus() {
76 SendHostStatus(ONLINE, kSuccessExitCode);
79 void HostStatusSender::SendHostStatus(HostStatus status,
80 HostExitCodes exit_code) {
81 SignalStrategy::State state = signal_strategy_->GetState();
82 if (state == SignalStrategy::CONNECTED) {
83 HOST_LOG << "Sending host status '"
84 << HostStatusToString(status)
85 << "' to "
86 << directory_bot_jid_;
88 iq_sender_->SendIq(buzz::STR_SET,
89 directory_bot_jid_,
90 CreateHostStatusMessage(status, exit_code),
91 IqSender::ReplyCallback());
92 } else {
93 HOST_LOG << "Cannot send host status to '"
94 << directory_bot_jid_
95 << " ' because the state of the SignalStrategy is "
96 << state;
100 scoped_ptr<XmlElement> HostStatusSender::CreateHostStatusMessage(
101 HostStatus status, HostExitCodes exit_code) {
102 // Create host status stanza.
103 scoped_ptr<XmlElement> host_status(new XmlElement(
104 QName(kChromotingXmlNamespace, kHostStatusTag)));
105 host_status->AddAttr(
106 QName(kChromotingXmlNamespace, kHostIdAttr), host_id_);
107 host_status->AddAttr(
108 QName(kChromotingXmlNamespace, kStatusAttr), HostStatusToString(status));
110 if (status == OFFLINE) {
111 host_status->AddAttr(
112 QName(kChromotingXmlNamespace, kExitCodeAttr),
113 ExitCodeToString(exit_code));
116 host_status->AddElement(CreateSignature(status, exit_code).release());
118 // Append host version.
119 scoped_ptr<XmlElement> version_tag(new XmlElement(
120 QName(kChromotingXmlNamespace, kHostVersionTag)));
121 version_tag->AddText(STRINGIZE(VERSION));
122 host_status->AddElement(version_tag.release());
124 // Append log message (which isn't signed).
125 scoped_ptr<XmlElement> log(ServerLogEntry::MakeStanza());
126 scoped_ptr<ServerLogEntry> log_entry(
127 MakeLogEntryForHostStatus(status, exit_code));
128 AddHostFieldsToLogEntry(log_entry.get());
129 log->AddElement(log_entry->ToStanza().release());
130 host_status->AddElement(log.release());
131 return host_status.Pass();
134 scoped_ptr<XmlElement> HostStatusSender::CreateSignature(
135 HostStatus status, HostExitCodes exit_code) {
136 scoped_ptr<XmlElement> signature_tag(new XmlElement(
137 QName(kChromotingXmlNamespace, kSignatureTag)));
139 // Number of seconds since epoch (Jan 1, 1970).
140 int64 time = static_cast<int64>(base::Time::Now().ToDoubleT());
141 std::string time_str(base::Int64ToString(time));
143 signature_tag->AddAttr(
144 QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str);
146 // Add a time stamp to the signature to prevent replay attacks.
147 std::string message =
148 signal_strategy_->GetLocalJid() +
149 " " +
150 time_str +
151 " " +
152 HostStatusToString(status);
154 if (status == OFFLINE)
155 message += std::string(" ") + ExitCodeToString(exit_code);
157 std::string signature(key_pair_->SignMessage(message));
158 signature_tag->AddText(signature);
160 return signature_tag.Pass();
163 } // namespace remoting