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" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "remoting/host/server_log_entry_host.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "remoting/signaling/iq_sender.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "remoting/signaling/server_log_entry.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "remoting/signaling/signal_strategy.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/libjingle/source/talk/xmpp/constants.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/webrtc/libjingle/xmllite/xmlelement.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing buzz::QName; 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing buzz::XmlElement; 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace remoting { 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace { 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kHostStatusTag[] = "host-status"; 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kHostIdAttr[] = "hostid"; 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kExitCodeAttr[] = "exit-code"; 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kHostVersionTag[] = "host-version"; 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kSignatureTag[] = "signature"; 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kStatusAttr[] = "status"; 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char kSignatureTimeAttr[] = "time"; 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char* const HostStatusSender::host_status_strings_[] = 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch{"OFFLINE", "ONLINE"}; 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochHostStatusSender::HostStatusSender( 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& host_id, 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SignalStrategy* signal_strategy, 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<RsaKeyPair> key_pair, 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& directory_bot_jid) 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : host_id_(host_id), 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_(signal_strategy), 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch key_pair_(key_pair), 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch directory_bot_jid_(directory_bot_jid) { 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(signal_strategy_); 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(key_pair_.get()); 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_->AddListener(this); 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochHostStatusSender::~HostStatusSender() { 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_->RemoveListener(this); 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::OnSignalStrategyStateChange( 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SignalStrategy::State state) { 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (state == SignalStrategy::CONNECTED) 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iq_sender_.reset(new IqSender(signal_strategy_)); 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else if (state == SignalStrategy::DISCONNECTED) 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iq_sender_.reset(); 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool HostStatusSender::OnSignalStrategyIncomingStanza( 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const XmlElement* stanza) { 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return false; 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::SendOfflineStatus(HostExitCodes exit_code) { 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SendHostStatus(OFFLINE, exit_code); 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::SendOnlineStatus() { 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SendHostStatus(ONLINE, kSuccessExitCode); 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid HostStatusSender::SendHostStatus(HostStatus status, 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostExitCodes exit_code) { 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SignalStrategy::State state = signal_strategy_->GetState(); 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (state == SignalStrategy::CONNECTED) { 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HOST_LOG << "Sending host status '" 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << HostStatusToString(status) 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << "' to " 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << directory_bot_jid_; 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iq_sender_->SendIq(buzz::STR_SET, 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch directory_bot_jid_, 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CreateHostStatusMessage(status, exit_code), 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch IqSender::ReplyCallback()); 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HOST_LOG << "Cannot send host status to '" 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << directory_bot_jid_ 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << " ' because the state of the SignalStrategy is " 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << state; 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_ptr<XmlElement> HostStatusSender::CreateHostStatusMessage( 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostStatus status, HostExitCodes exit_code) { 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create host status stanza. 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> host_status(new XmlElement( 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kHostStatusTag))); 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddAttr( 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kHostIdAttr), host_id_); 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddAttr( 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kStatusAttr), HostStatusToString(status)); 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (status == OFFLINE) { 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddAttr( 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kExitCodeAttr), 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExitCodeToString(exit_code)); 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddElement(CreateSignature(status, exit_code).release()); 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Append host version. 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> version_tag(new XmlElement( 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kHostVersionTag))); 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch version_tag->AddText(STRINGIZE(VERSION)); 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddElement(version_tag.release()); 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Append log message (which isn't signed). 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> log(ServerLogEntry::MakeStanza()); 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<ServerLogEntry> log_entry( 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MakeLogEntryForHostStatus(status, exit_code)); 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AddHostFieldsToLogEntry(log_entry.get()); 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch log->AddElement(log_entry->ToStanza().release()); 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch host_status->AddElement(log.release()); 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return host_status.Pass(); 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_ptr<XmlElement> HostStatusSender::CreateSignature( 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostStatus status, HostExitCodes exit_code) { 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<XmlElement> signature_tag(new XmlElement( 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kSignatureTag))); 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Number of seconds since epoch (Jan 1, 1970). 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 time = static_cast<int64>(base::Time::Now().ToDoubleT()); 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string time_str(base::Int64ToString(time)); 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signature_tag->AddAttr( 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str); 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Add a time stamp to the signature to prevent replay attacks. 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string message = 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signal_strategy_->GetLocalJid() + 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " " + 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch time_str + 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch " " + 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch HostStatusToString(status); 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (status == OFFLINE) 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch message += std::string(" ") + ExitCodeToString(exit_code); 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string signature(key_pair_->SignMessage(message)); 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch signature_tag->AddText(signature); 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return signature_tag.Pass(); 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace remoting 164