host_status_sender.cc revision f2477e01787aa58f445919b809d89e252beef54f
17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "remoting/host/host_status_sender.h" 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/string_number_conversions.h" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/stringize_macros.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/time/time.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "remoting/base/constants.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "remoting/base/logging.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "remoting/host/server_log_entry.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "remoting/jingle_glue/iq_sender.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "remoting/jingle_glue/signal_strategy.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/libjingle/source/talk/xmpp/constants.h" 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing buzz::QName; 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing buzz::XmlElement; 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace remoting { 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace { 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kHostStatusTag[] = "host-status"; 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kHostIdAttr[] = "hostid"; 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kExitCodeAttr[] = "exit-code"; 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kHostVersionTag[] = "host-version"; 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kSignatureTag[] = "signature"; 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kStatusAttr[] = "status"; 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kSignatureTimeAttr[] = "time"; 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char* const HostStatusSender::host_status_strings_[] = 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch{"OFFLINE", "ONLINE"}; 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochHostStatusSender::HostStatusSender( 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& host_id, 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SignalStrategy* signal_strategy, 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<RsaKeyPair> key_pair, 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& directory_bot_jid) 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : host_id_(host_id), 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_(signal_strategy), 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch key_pair_(key_pair), 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch directory_bot_jid_(directory_bot_jid) { 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(signal_strategy_); 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(key_pair_.get()); 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_->AddListener(this); 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochHostStatusSender::~HostStatusSender() { 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_->RemoveListener(this); 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::OnSignalStrategyStateChange( 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SignalStrategy::State state) { 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (state == SignalStrategy::CONNECTED) 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iq_sender_.reset(new IqSender(signal_strategy_)); 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else if (state == SignalStrategy::DISCONNECTED) 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iq_sender_.reset(); 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool HostStatusSender::OnSignalStrategyIncomingStanza( 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const XmlElement* stanza) { 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::SendOfflineStatus(HostExitCodes exit_code) { 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SendHostStatus(OFFLINE, exit_code); 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::SendOnlineStatus() { 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SendHostStatus(ONLINE, kSuccessExitCode); 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::SendHostStatus(HostStatus status, 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostExitCodes exit_code) { 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SignalStrategy::State state = signal_strategy_->GetState(); 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (state == SignalStrategy::CONNECTED) { 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HOST_LOG << "Sending host status '" 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << HostStatusToString(status) 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << "' to " 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << directory_bot_jid_; 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iq_sender_->SendIq(buzz::STR_SET, 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch directory_bot_jid_, 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateHostStatusMessage(status, exit_code), 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IqSender::ReplyCallback()); 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HOST_LOG << "Cannot send host status to '" 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << directory_bot_jid_ 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << " ' because the state of the SignalStrategy is " 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << state; 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_ptr<XmlElement> HostStatusSender::CreateHostStatusMessage( 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostStatus status, HostExitCodes exit_code) { 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create host status stanza. 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> host_status(new XmlElement( 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kHostStatusTag))); 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddAttr( 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kHostIdAttr), host_id_); 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddAttr( 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kStatusAttr), HostStatusToString(status)); 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (status == OFFLINE) { 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddAttr( 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kExitCodeAttr), 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExitCodeToString(exit_code)); 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddElement(CreateSignature(status, exit_code).release()); 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Append host version. 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> version_tag(new XmlElement( 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kHostVersionTag))); 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch version_tag->AddText(STRINGIZE(VERSION)); 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddElement(version_tag.release()); 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Append log message (which isn't signed). 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> log(ServerLogEntry::MakeStanza()); 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<ServerLogEntry> log_entry( 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ServerLogEntry::MakeForHostStatus(status, exit_code)); 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch log_entry->AddHostFields(); 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch log->AddElement(log_entry->ToStanza().release()); 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddElement(log.release()); 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return host_status.Pass(); 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_ptr<XmlElement> HostStatusSender::CreateSignature( 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostStatus status, HostExitCodes exit_code) { 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> signature_tag(new XmlElement( 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kSignatureTag))); 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Number of seconds since epoch (Jan 1, 1970). 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 time = static_cast<int64>(base::Time::Now().ToDoubleT()); 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string time_str(base::Int64ToString(time)); 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signature_tag->AddAttr( 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str); 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Add a time stamp to the signature to prevent replay attacks. 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string message = 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_->GetLocalJid() + 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " " + 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch time_str + 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " " + 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostStatusToString(status); 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (status == OFFLINE) 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch message += std::string(" ") + ExitCodeToString(exit_code); 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string signature(key_pair_->SignMessage(message)); 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signature_tag->AddText(signature); 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return signature_tag.Pass(); 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace remoting 163