Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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. | |
| 4 | |
| 5 #include "remoting/host/host_status_sender.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/strings/string_number_conversions.h" | |
| 9 #include "base/strings/stringize_macros.h" | |
| 10 #include "remoting/base/constants.h" | |
| 11 #include "remoting/host/server_log_entry.h" | |
| 12 #include "remoting/jingle_glue/iq_sender.h" | |
| 13 #include "remoting/jingle_glue/signal_strategy.h" | |
| 14 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | |
| 15 #include "third_party/libjingle/source/talk/xmpp/constants.h" | |
| 16 | |
| 17 using buzz::QName; | |
| 18 using buzz::XmlElement; | |
| 19 | |
| 20 namespace remoting { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 const char kHostStatusTag[] = "host-status"; | |
| 25 const char kHostIdAttr[] = "hostid"; | |
| 26 const char kExitCodeAttr[] = "exit-code"; | |
| 27 const char kHostVersionTag[] = "host-version"; | |
| 28 const char kSignatureTag[] = "signature"; | |
| 29 const char kStatusAttr[] = "status"; | |
| 30 const char kSignatureTimeAttr[] = "time"; | |
| 31 | |
| 32 } // namespace | |
| 33 | |
| 34 HostStatusSender::HostStatusSender( | |
| 35 const std::string& host_id, | |
| 36 SignalStrategy* signal_strategy, | |
| 37 scoped_refptr<RsaKeyPair> key_pair, | |
| 38 const std::string& directory_bot_jid) | |
| 39 : host_id_(host_id), | |
| 40 signal_strategy_(signal_strategy), | |
| 41 key_pair_(key_pair), | |
| 42 directory_bot_jid_(directory_bot_jid) { | |
| 43 DCHECK(signal_strategy_); | |
| 44 DCHECK(key_pair_.get()); | |
| 45 | |
| 46 signal_strategy_->AddListener(this); | |
| 47 } | |
| 48 | |
| 49 HostStatusSender::~HostStatusSender() { | |
| 50 signal_strategy_->RemoveListener(this); | |
| 51 } | |
| 52 | |
| 53 void HostStatusSender::OnSignalStrategyStateChange( | |
| 54 SignalStrategy::State state) { | |
| 55 if (state == SignalStrategy::CONNECTED) | |
| 56 iq_sender_.reset(new IqSender(signal_strategy_)); | |
| 57 else if (state == SignalStrategy::DISCONNECTED) | |
| 58 iq_sender_.reset(); | |
| 59 } | |
| 60 | |
| 61 bool HostStatusSender::OnSignalStrategyIncomingStanza( | |
| 62 const XmlElement* stanza) { | |
| 63 return false; | |
| 64 } | |
| 65 | |
| 66 void HostStatusSender::SendOfflineStatus(int exit_code) { | |
| 67 SendHostStatus(OFFLINE, exit_code); | |
| 68 } | |
| 69 | |
| 70 void HostStatusSender::SendOnlineStatus() { | |
| 71 SendHostStatus(ONLINE, 0); | |
| 72 } | |
| 73 | |
| 74 void HostStatusSender::SendHostStatus(HostStatus status, int exit_code) { | |
| 75 SignalStrategy::State state = signal_strategy_->GetState(); | |
| 76 if (state == SignalStrategy::CONNECTED) { | |
| 77 LOG(INFO) << "Sending host status '" | |
| 78 << status | |
| 79 << "' to " | |
| 80 << directory_bot_jid_; | |
| 81 | |
| 82 iq_sender_->SendIq(buzz::STR_SET, | |
| 83 directory_bot_jid_, | |
| 84 CreateHostStatusMessage(status, exit_code), | |
| 85 IqSender::ReplyCallback()); | |
| 86 } else { | |
| 87 LOG(INFO) << "Cannot send host status to '" | |
| 88 << directory_bot_jid_ | |
| 89 << " ' because the state of the SignalStrategy is " | |
| 90 << state; | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 scoped_ptr<XmlElement> HostStatusSender::CreateHostStatusMessage( | |
| 95 HostStatus status, int exit_code) { | |
| 96 // Create host status stanza. | |
| 97 scoped_ptr<XmlElement> host_status(new XmlElement( | |
| 98 QName(kChromotingXmlNamespace, kHostStatusTag))); | |
| 99 host_status->AddAttr( | |
| 100 QName(kChromotingXmlNamespace, kHostIdAttr), host_id_); | |
| 101 host_status->AddAttr( | |
| 102 QName(kChromotingXmlNamespace, kStatusAttr), base::IntToString(status)); | |
|
rmsousa
2013/07/04 01:20:14
we typically don't send/receive enums as raw numbe
weitao
2013/07/09 00:37:40
Done.
| |
| 103 | |
| 104 if (status == OFFLINE) { | |
| 105 host_status->AddAttr( | |
| 106 QName(kChromotingXmlNamespace, kExitCodeAttr), | |
|
rmsousa
2013/07/04 01:20:14
For this one, I'm inclined to say that we should a
weitao
2013/07/09 00:37:40
Done.
| |
| 107 base::IntToString(exit_code)); | |
| 108 } | |
| 109 | |
| 110 host_status->AddElement(CreateSignature(status, exit_code).release()); | |
| 111 | |
| 112 // Append host version. | |
| 113 scoped_ptr<XmlElement> version_tag(new XmlElement( | |
| 114 QName(kChromotingXmlNamespace, kHostVersionTag))); | |
| 115 version_tag->AddText(STRINGIZE(VERSION)); | |
| 116 host_status->AddElement(version_tag.release()); | |
| 117 | |
| 118 // Append log message (which isn't signed). | |
| 119 scoped_ptr<XmlElement> log(ServerLogEntry::MakeStanza()); | |
| 120 scoped_ptr<ServerLogEntry> log_entry(ServerLogEntry::MakeForHostStatus()); | |
| 121 log_entry->AddHostFields(); | |
| 122 log->AddElement(log_entry->ToStanza().release()); | |
|
rmsousa
2013/07/04 01:20:14
this log message should include the status and exi
weitao
2013/07/09 00:37:40
Done.
| |
| 123 host_status->AddElement(log.release()); | |
| 124 return host_status.Pass(); | |
| 125 } | |
| 126 | |
| 127 scoped_ptr<XmlElement> HostStatusSender::CreateSignature( | |
| 128 HostStatus status, int exit_code) { | |
| 129 scoped_ptr<XmlElement> signature_tag(new XmlElement( | |
| 130 QName(kChromotingXmlNamespace, kSignatureTag))); | |
| 131 | |
| 132 // Number of seconds since epoch (Jan 1, 1970). | |
| 133 int64 time = static_cast<int64>(base::Time::Now().ToDoubleT()); | |
| 134 std::string time_str(base::Int64ToString(time)); | |
| 135 | |
| 136 signature_tag->AddAttr( | |
| 137 QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str); | |
| 138 | |
| 139 // Add a time stamp to the signature to prevent replay attacks. | |
| 140 std::string message = | |
| 141 signal_strategy_->GetLocalJid() + | |
| 142 " " + | |
| 143 time_str + | |
| 144 " " + | |
| 145 base::IntToString(status); | |
| 146 | |
| 147 if (status == OFFLINE) | |
| 148 message += " " + base::IntToString(exit_code); | |
| 149 | |
| 150 std::string signature(key_pair_->SignMessage(message)); | |
| 151 signature_tag->AddText(signature); | |
| 152 | |
| 153 return signature_tag.Pass(); | |
| 154 } | |
| 155 | |
| 156 } // namespace remoting | |
| OLD | NEW |