diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-27 21:38:46 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-27 21:38:46 +0000 |
commit | 88b460b939077577521fe6119a3682b17992eeae (patch) | |
tree | 97edbd2852b18015c524842a82d4459f5f21b2d6 /remoting | |
parent | 02de972eead4d567089d97635328ed520091389d (diff) | |
download | chromium_src-88b460b939077577521fe6119a3682b17992eeae.zip chromium_src-88b460b939077577521fe6119a3682b17992eeae.tar.gz chromium_src-88b460b939077577521fe6119a3682b17992eeae.tar.bz2 |
Move ContentDescription class to a separate file.
BUG=None
TEST=Compiles
Review URL: http://codereview.chromium.org/7261011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90650 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/protocol/content_description.cc | 373 | ||||
-rw-r--r-- | remoting/protocol/content_description.h | 66 | ||||
-rw-r--r-- | remoting/protocol/jingle_session_manager.cc | 358 | ||||
-rw-r--r-- | remoting/protocol/jingle_session_manager.h | 40 | ||||
-rw-r--r-- | remoting/remoting.gyp | 2 |
5 files changed, 447 insertions, 392 deletions
diff --git a/remoting/protocol/content_description.cc b/remoting/protocol/content_description.cc new file mode 100644 index 0000000..df289d8 --- /dev/null +++ b/remoting/protocol/content_description.cc @@ -0,0 +1,373 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/protocol/content_description.h" + +#include "base/base64.h" +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "remoting/base/constants.h" +#include "remoting/proto/auth.pb.h" +#include "third_party/libjingle/source/talk/xmllite/xmlelement.h" + +using buzz::QName; +using buzz::XmlElement; + +namespace remoting { +namespace protocol { + +namespace { + +const char kDefaultNs[] = ""; + +const char kChromotingContentName[] = "chromoting"; + +// Following constants are used to format session description in XML. +const char kDescriptionTag[] = "description"; +const char kControlTag[] = "control"; +const char kEventTag[] = "event"; +const char kVideoTag[] = "video"; +const char kResolutionTag[] = "initial-resolution"; +const char kAuthenticationTag[] = "authentication"; +const char kCertificateTag[] = "certificate"; +const char kMasterKeyTag[] = "master-key"; +const char kAuthTokenTag[] = "auth-token"; + +const char kTransportAttr[] = "transport"; +const char kVersionAttr[] = "version"; +const char kCodecAttr[] = "codec"; +const char kWidthAttr[] = "width"; +const char kHeightAttr[] = "height"; + +const char kStreamTransport[] = "stream"; +const char kDatagramTransport[] = "datagram"; +const char kSrtpTransport[] = "srtp"; +const char kRtpDtlsTransport[] = "rtp-dtls"; + +const char kVp8Codec[] = "vp8"; +const char kZipCodec[] = "zip"; + +const char* GetTransportName(ChannelConfig::TransportType type) { + switch (type) { + case ChannelConfig::TRANSPORT_STREAM: + return kStreamTransport; + case ChannelConfig::TRANSPORT_DATAGRAM: + return kDatagramTransport; + case ChannelConfig::TRANSPORT_SRTP: + return kSrtpTransport; + case ChannelConfig::TRANSPORT_RTP_DTLS: + return kRtpDtlsTransport; + } + NOTREACHED(); + return NULL; +} + +const char* GetCodecName(ChannelConfig::Codec type) { + switch (type) { + case ChannelConfig::CODEC_VP8: + return kVp8Codec; + case ChannelConfig::CODEC_ZIP: + return kZipCodec; + default: + break; + } + NOTREACHED(); + return NULL; +} + + +// Format a channel configuration tag for chromotocol session description, +// e.g. for video channel: +// <video transport="srtp" version="1" codec="vp8" /> +XmlElement* FormatChannelConfig(const ChannelConfig& config, + const std::string& tag_name) { + XmlElement* result = new XmlElement( + QName(kChromotingXmlNamespace, tag_name)); + + result->AddAttr(QName(kDefaultNs, kTransportAttr), + GetTransportName(config.transport)); + + result->AddAttr(QName(kDefaultNs, kVersionAttr), + base::IntToString(config.version)); + + if (config.codec != ChannelConfig::CODEC_UNDEFINED) { + result->AddAttr(QName(kDefaultNs, kCodecAttr), + GetCodecName(config.codec)); + } + + return result; +} + +bool ParseTransportName(const std::string& value, + ChannelConfig::TransportType* transport) { + if (value == kStreamTransport) { + *transport = ChannelConfig::TRANSPORT_STREAM; + } else if (value == kDatagramTransport) { + *transport = ChannelConfig::TRANSPORT_DATAGRAM; + } else if (value == kSrtpTransport) { + *transport = ChannelConfig::TRANSPORT_SRTP; + } else if (value == kRtpDtlsTransport) { + *transport = ChannelConfig::TRANSPORT_RTP_DTLS; + } else { + return false; + } + return true; +} + +bool ParseCodecName(const std::string& value, ChannelConfig::Codec* codec) { + if (value == kVp8Codec) { + *codec = ChannelConfig::CODEC_VP8; + } else if (value == kZipCodec) { + *codec = ChannelConfig::CODEC_ZIP; + } else { + return false; + } + return true; +} + +// Returns false if the element is invalid. +bool ParseChannelConfig(const XmlElement* element, bool codec_required, + ChannelConfig* config) { + if (!ParseTransportName(element->Attr(QName(kDefaultNs, kTransportAttr)), + &config->transport) || + !base::StringToInt(element->Attr(QName(kDefaultNs, kVersionAttr)), + &config->version)) { + return false; + } + + if (codec_required) { + if (!ParseCodecName(element->Attr(QName(kDefaultNs, kCodecAttr)), + &config->codec)) { + return false; + } + } else { + config->codec = ChannelConfig::CODEC_UNDEFINED; + } + + return true; +} + +} // namespace + +ContentDescription::ContentDescription( + const CandidateSessionConfig* candidate_config, + const std::string& auth_token, + const std::string& master_key, + scoped_refptr<net::X509Certificate> certificate) + : candidate_config_(candidate_config), + auth_token_(auth_token), + master_key_(master_key), + certificate_(certificate) { +} + +ContentDescription::~ContentDescription() { } + +// ToXml() creates content description for chromoting session. The +// description looks as follows: +// <description xmlns="google:remoting"> +// <control transport="stream" version="1" /> +// <event transport="datagram" version="1" /> +// <video transport="srtp" codec="vp8" version="1" /> +// <initial-resolution width="800" height="600" /> +// <authentication> +// <certificate>[BASE64 Encoded Certificate]</certificate> +// <master-key>[master key encrypted with hosts +// public key encoded with BASE64]</master-key> +// <auth-token>...</auth-token> // IT2Me only. +// </authentication> +// </description> +// +XmlElement* ContentDescription::ToXml() const { + XmlElement* root = new XmlElement( + QName(kChromotingXmlNamespace, kDescriptionTag), true); + + std::vector<ChannelConfig>::const_iterator it; + + for (it = config()->control_configs().begin(); + it != config()->control_configs().end(); ++it) { + root->AddElement(FormatChannelConfig(*it, kControlTag)); + } + + for (it = config()->event_configs().begin(); + it != config()->event_configs().end(); ++it) { + root->AddElement(FormatChannelConfig(*it, kEventTag)); + } + + for (it = config()->video_configs().begin(); + it != config()->video_configs().end(); ++it) { + root->AddElement(FormatChannelConfig(*it, kVideoTag)); + } + + XmlElement* resolution_tag = new XmlElement( + QName(kChromotingXmlNamespace, kResolutionTag)); + resolution_tag->AddAttr(QName(kDefaultNs, kWidthAttr), + base::IntToString( + config()->initial_resolution().width)); + resolution_tag->AddAttr(QName(kDefaultNs, kHeightAttr), + base::IntToString( + config()->initial_resolution().height)); + root->AddElement(resolution_tag); + + if (certificate() || !auth_token().empty()) { + XmlElement* authentication_tag = new XmlElement( + QName(kChromotingXmlNamespace, kAuthenticationTag)); + + if (certificate()) { + XmlElement* certificate_tag = new XmlElement( + QName(kChromotingXmlNamespace, kCertificateTag)); + + std::string der_cert; + if (!certificate()->GetDEREncoded(&der_cert)) { + LOG(DFATAL) << "Cannot obtain DER encoded certificate"; + } + + std::string base64_cert; + if (!base::Base64Encode(der_cert, &base64_cert)) { + LOG(DFATAL) << "Cannot perform base64 encode on certificate"; + } + + certificate_tag->SetBodyText(base64_cert); + authentication_tag->AddElement(certificate_tag); + } + + if (!master_key().empty()) { + XmlElement* master_key_tag = new XmlElement( + QName(kChromotingXmlNamespace, kMasterKeyTag)); + + std::string master_key_base64; + if (!base::Base64Encode(master_key(), &master_key_base64)) { + LOG(DFATAL) << "Cannot perform base64 encode on master key"; + } + + master_key_tag->SetBodyText(master_key_base64); + authentication_tag->AddElement(master_key_tag); + } + + if (!auth_token().empty()) { + XmlElement* auth_token_tag = new XmlElement( + QName(kChromotingXmlNamespace, kAuthTokenTag)); + auth_token_tag->SetBodyText(auth_token()); + authentication_tag->AddElement(auth_token_tag); + } + + root->AddElement(authentication_tag); + } + + return root; +} + +// static +cricket::ContentDescription* ContentDescription::ParseXml( + const XmlElement* element) { + if (element->Name() == QName(kChromotingXmlNamespace, kDescriptionTag)) { + scoped_ptr<CandidateSessionConfig> config( + CandidateSessionConfig::CreateEmpty()); + const XmlElement* child = NULL; + + // <control> tags. + QName control_tag(kChromotingXmlNamespace, kControlTag); + child = element->FirstNamed(control_tag); + while (child) { + ChannelConfig channel_config; + if (!ParseChannelConfig(child, false, &channel_config)) + return NULL; + config->mutable_control_configs()->push_back(channel_config); + child = child->NextNamed(control_tag); + } + + // <event> tags. + QName event_tag(kChromotingXmlNamespace, kEventTag); + child = element->FirstNamed(event_tag); + while (child) { + ChannelConfig channel_config; + if (!ParseChannelConfig(child, false, &channel_config)) + return NULL; + config->mutable_event_configs()->push_back(channel_config); + child = child->NextNamed(event_tag); + } + + // <video> tags. + QName video_tag(kChromotingXmlNamespace, kVideoTag); + child = element->FirstNamed(video_tag); + while (child) { + ChannelConfig channel_config; + if (!ParseChannelConfig(child, true, &channel_config)) + return NULL; + config->mutable_video_configs()->push_back(channel_config); + child = child->NextNamed(video_tag); + } + + // <initial-resolution> tag. + child = element->FirstNamed(QName(kChromotingXmlNamespace, kResolutionTag)); + if (!child) + return NULL; // Resolution must always be specified. + int width; + int height; + if (!base::StringToInt(child->Attr(QName(kDefaultNs, kWidthAttr)), + &width) || + !base::StringToInt(child->Attr(QName(kDefaultNs, kHeightAttr)), + &height)) { + return NULL; + } + ScreenResolution resolution(width, height); + if (!resolution.IsValid()) { + return NULL; + } + + *config->mutable_initial_resolution() = resolution; + + // Parse authentication information. + scoped_refptr<net::X509Certificate> certificate; + std::string auth_token; + std::string master_key; + child = element->FirstNamed(QName(kChromotingXmlNamespace, + kAuthenticationTag)); + if (child) { + // Parse the certificate. + const XmlElement* cert_tag = + child->FirstNamed(QName(kChromotingXmlNamespace, kCertificateTag)); + if (cert_tag) { + std::string base64_cert = cert_tag->BodyText(); + std::string der_cert; + if (!base::Base64Decode(base64_cert, &der_cert)) { + LOG(ERROR) << "Failed to decode certificate received from the peer."; + return NULL; + } + + certificate = net::X509Certificate::CreateFromBytes(der_cert.data(), + der_cert.length()); + if (!certificate) { + LOG(ERROR) << "Failed to create platform-specific certificate handle"; + return NULL; + } + } + + // Parse master-key. + const XmlElement* master_key_tag = + child->FirstNamed(QName(kChromotingXmlNamespace, kMasterKeyTag)); + if (master_key_tag) { + if (!base::Base64Decode(master_key_tag->BodyText(), &master_key)) { + LOG(ERROR) << "Failed to decode master-key received from the peer."; + return NULL; + } + master_key = master_key_tag->BodyText(); + } + + // Parse auth-token. + const XmlElement* auth_token_tag = + child->FirstNamed(QName(kChromotingXmlNamespace, kAuthTokenTag)); + if (auth_token_tag) { + auth_token = auth_token_tag->BodyText(); + } + } + + return new ContentDescription(config.release(), auth_token, master_key, + certificate); + } + LOG(ERROR) << "Invalid description: " << element->Str(); + return NULL; +} + +} // namespace protocol +} // namespace remoting diff --git a/remoting/protocol/content_description.h b/remoting/protocol/content_description.h new file mode 100644 index 0000000..3759838 --- /dev/null +++ b/remoting/protocol/content_description.h @@ -0,0 +1,66 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_PROTOCOL_CONTENT_DESCRIPTION_H_ +#define REMOTING_PROTOCOL_CONTENT_DESCRIPTION_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" +#include "net/base/x509_certificate.h" +#include "remoting/protocol/session_config.h" +#include "third_party/libjingle/source/talk/p2p/base/sessiondescription.h" + +namespace buzz { +class XmlElement; +} // namespace buzz + +namespace remoting { +namespace protocol { + +// ContentDescription used for chromoting sessions. It contains the information +// from the content description stanza in the session intialization handshake. +// +// This class also provides a type abstraction so that the Chromotocol Session +// interface does not need to depend on libjingle. +class ContentDescription : public cricket::ContentDescription { + public: + explicit ContentDescription(const CandidateSessionConfig* config, + const std::string& auth_token, + const std::string& master_key, + scoped_refptr<net::X509Certificate> certificate); + virtual ~ContentDescription(); + + const CandidateSessionConfig* config() const { + return candidate_config_.get(); + } + + const std::string& auth_token() const { return auth_token_; } + const std::string& master_key() const { return master_key_; } + scoped_refptr<net::X509Certificate> certificate() const { + return certificate_; + } + + buzz::XmlElement* ToXml() const; + + static cricket::ContentDescription* ParseXml(const buzz::XmlElement* element); + + private: + scoped_ptr<const CandidateSessionConfig> candidate_config_; + + // This may contain the initiating, or the accepting token depending on + // context. + std::string auth_token_; + + // Master key used for the session encrypted with the hosts key. + std::string master_key_; + + scoped_refptr<net::X509Certificate> certificate_; +}; + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_CONTENT_DESCRIPTION_H_ diff --git a/remoting/protocol/jingle_session_manager.cc b/remoting/protocol/jingle_session_manager.cc index f665553..0c6e272 100644 --- a/remoting/protocol/jingle_session_manager.cc +++ b/remoting/protocol/jingle_session_manager.cc @@ -2,172 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <limits> - #include "remoting/protocol/jingle_session_manager.h" -#include "base/base64.h" +#include <limits> + #include "base/message_loop.h" -#include "base/rand_util.h" -#include "base/string_number_conversions.h" #include "remoting/base/constants.h" -#include "remoting/proto/auth.pb.h" #include "third_party/libjingle/source/talk/p2p/base/constants.h" #include "third_party/libjingle/source/talk/p2p/base/transport.h" #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" -using buzz::QName; using buzz::XmlElement; namespace remoting { namespace protocol { -namespace { - -const char kDefaultNs[] = ""; - -const char kChromotingContentName[] = "chromoting"; - -// Following constants are used to format session description in XML. -const char kDescriptionTag[] = "description"; -const char kControlTag[] = "control"; -const char kEventTag[] = "event"; -const char kVideoTag[] = "video"; -const char kResolutionTag[] = "initial-resolution"; -const char kAuthenticationTag[] = "authentication"; -const char kCertificateTag[] = "certificate"; -const char kMasterKeyTag[] = "master-key"; -const char kAuthTokenTag[] = "auth-token"; - -const char kTransportAttr[] = "transport"; -const char kVersionAttr[] = "version"; -const char kCodecAttr[] = "codec"; -const char kWidthAttr[] = "width"; -const char kHeightAttr[] = "height"; - -const char kStreamTransport[] = "stream"; -const char kDatagramTransport[] = "datagram"; -const char kSrtpTransport[] = "srtp"; -const char kRtpDtlsTransport[] = "rtp-dtls"; - -const char kVp8Codec[] = "vp8"; -const char kZipCodec[] = "zip"; - -const char* GetTransportName(ChannelConfig::TransportType type) { - switch (type) { - case ChannelConfig::TRANSPORT_STREAM: - return kStreamTransport; - case ChannelConfig::TRANSPORT_DATAGRAM: - return kDatagramTransport; - case ChannelConfig::TRANSPORT_SRTP: - return kSrtpTransport; - case ChannelConfig::TRANSPORT_RTP_DTLS: - return kRtpDtlsTransport; - } - NOTREACHED(); - return NULL; -} - -const char* GetCodecName(ChannelConfig::Codec type) { - switch (type) { - case ChannelConfig::CODEC_VP8: - return kVp8Codec; - case ChannelConfig::CODEC_ZIP: - return kZipCodec; - default: - break; - } - NOTREACHED(); - return NULL; -} - - -// Format a channel configuration tag for chromotocol session description, -// e.g. for video channel: -// <video transport="srtp" version="1" codec="vp8" /> -XmlElement* FormatChannelConfig(const ChannelConfig& config, - const std::string& tag_name) { - XmlElement* result = new XmlElement( - QName(kChromotingXmlNamespace, tag_name)); - - result->AddAttr(QName(kDefaultNs, kTransportAttr), - GetTransportName(config.transport)); - - result->AddAttr(QName(kDefaultNs, kVersionAttr), - base::IntToString(config.version)); - - if (config.codec != ChannelConfig::CODEC_UNDEFINED) { - result->AddAttr(QName(kDefaultNs, kCodecAttr), - GetCodecName(config.codec)); - } - - return result; -} - -bool ParseTransportName(const std::string& value, - ChannelConfig::TransportType* transport) { - if (value == kStreamTransport) { - *transport = ChannelConfig::TRANSPORT_STREAM; - } else if (value == kDatagramTransport) { - *transport = ChannelConfig::TRANSPORT_DATAGRAM; - } else if (value == kSrtpTransport) { - *transport = ChannelConfig::TRANSPORT_SRTP; - } else if (value == kRtpDtlsTransport) { - *transport = ChannelConfig::TRANSPORT_RTP_DTLS; - } else { - return false; - } - return true; -} - -bool ParseCodecName(const std::string& value, ChannelConfig::Codec* codec) { - if (value == kVp8Codec) { - *codec = ChannelConfig::CODEC_VP8; - } else if (value == kZipCodec) { - *codec = ChannelConfig::CODEC_ZIP; - } else { - return false; - } - return true; -} - -// Returns false if the element is invalid. -bool ParseChannelConfig(const XmlElement* element, bool codec_required, - ChannelConfig* config) { - if (!ParseTransportName(element->Attr(QName(kDefaultNs, kTransportAttr)), - &config->transport) || - !base::StringToInt(element->Attr(QName(kDefaultNs, kVersionAttr)), - &config->version)) { - return false; - } - - if (codec_required) { - if (!ParseCodecName(element->Attr(QName(kDefaultNs, kCodecAttr)), - &config->codec)) { - return false; - } - } else { - config->codec = ChannelConfig::CODEC_UNDEFINED; - } - - return true; -} - -} // namespace - -ContentDescription::ContentDescription( - const CandidateSessionConfig* candidate_config, - const std::string& auth_token, - const std::string& master_key, - scoped_refptr<net::X509Certificate> certificate) - : candidate_config_(candidate_config), - auth_token_(auth_token), - master_key_(master_key), - certificate_(certificate) { -} - -ContentDescription::~ContentDescription() { } - JingleSessionManager::JingleSessionManager(MessageLoop* message_loop) : message_loop_(message_loop), cricket_session_manager_(NULL), @@ -373,131 +222,10 @@ bool JingleSessionManager::ParseContent( const XmlElement* element, const cricket::ContentDescription** content, cricket::ParseError* error) { - if (element->Name() == QName(kChromotingXmlNamespace, kDescriptionTag)) { - scoped_ptr<CandidateSessionConfig> config( - CandidateSessionConfig::CreateEmpty()); - const XmlElement* child = NULL; - - // <control> tags. - QName control_tag(kChromotingXmlNamespace, kControlTag); - child = element->FirstNamed(control_tag); - while (child) { - ChannelConfig channel_config; - if (!ParseChannelConfig(child, false, &channel_config)) - return false; - config->mutable_control_configs()->push_back(channel_config); - child = child->NextNamed(control_tag); - } - - // <event> tags. - QName event_tag(kChromotingXmlNamespace, kEventTag); - child = element->FirstNamed(event_tag); - while (child) { - ChannelConfig channel_config; - if (!ParseChannelConfig(child, false, &channel_config)) - return false; - config->mutable_event_configs()->push_back(channel_config); - child = child->NextNamed(event_tag); - } - - // <video> tags. - QName video_tag(kChromotingXmlNamespace, kVideoTag); - child = element->FirstNamed(video_tag); - while (child) { - ChannelConfig channel_config; - if (!ParseChannelConfig(child, true, &channel_config)) - return false; - config->mutable_video_configs()->push_back(channel_config); - child = child->NextNamed(video_tag); - } - - // <initial-resolution> tag. - child = element->FirstNamed(QName(kChromotingXmlNamespace, kResolutionTag)); - if (!child) - return false; // Resolution must always be specified. - int width; - int height; - if (!base::StringToInt(child->Attr(QName(kDefaultNs, kWidthAttr)), - &width) || - !base::StringToInt(child->Attr(QName(kDefaultNs, kHeightAttr)), - &height)) { - return false; - } - ScreenResolution resolution(width, height); - if (!resolution.IsValid()) { - return false; - } - - *config->mutable_initial_resolution() = resolution; - - // Parse authentication information. - scoped_refptr<net::X509Certificate> certificate; - std::string auth_token; - std::string master_key; - child = element->FirstNamed(QName(kChromotingXmlNamespace, - kAuthenticationTag)); - if (child) { - // Parse the certificate. - const XmlElement* cert_tag = - child->FirstNamed(QName(kChromotingXmlNamespace, kCertificateTag)); - if (cert_tag) { - std::string base64_cert = cert_tag->BodyText(); - std::string der_cert; - if (!base::Base64Decode(base64_cert, &der_cert)) { - LOG(ERROR) << "Failed to decode certificate received from the peer."; - return false; - } - - certificate = net::X509Certificate::CreateFromBytes(der_cert.data(), - der_cert.length()); - if (!certificate) { - LOG(ERROR) << "Failed to create platform-specific certificate handle"; - return false; - } - } - - // Parse master-key. - const XmlElement* master_key_tag = - child->FirstNamed(QName(kChromotingXmlNamespace, kMasterKeyTag)); - if (master_key_tag) { - if (!base::Base64Decode(master_key_tag->BodyText(), &master_key)) { - LOG(ERROR) << "Failed to decode master-key received from the peer."; - return false; - } - master_key = master_key_tag->BodyText(); - } - - // Parse auth-token. - const XmlElement* auth_token_tag = - child->FirstNamed(QName(kChromotingXmlNamespace, kAuthTokenTag)); - if (auth_token_tag) { - auth_token = auth_token_tag->BodyText(); - } - } - - *content = new ContentDescription(config.release(), auth_token, master_key, - certificate); - return true; - } - LOG(ERROR) << "Invalid description: " << element->Str(); - return false; + *content = ContentDescription::ParseXml(element); + return *content != NULL; } -// WriteContent creates content description for chromoting session. The -// description looks as follows: -// <description xmlns="google:remoting"> -// <control transport="stream" version="1" /> -// <event transport="datagram" version="1" /> -// <video transport="srtp" codec="vp8" version="1" /> -// <initial-resolution width="800" height="600" /> -// <authentication> -// <certificate>[BASE64 Encoded Certificate]</certificate> -// <master-key>[master key encrypted with hosts -// public key encoded with BASE64]</master-key> -// <auth-token>...</auth-token> // Me2Mom only. -// </authentication> -// </description> -// bool JingleSessionManager::WriteContent( cricket::SignalingProtocol protocol, const cricket::ContentDescription* content, @@ -506,83 +234,7 @@ bool JingleSessionManager::WriteContent( const ContentDescription* desc = static_cast<const ContentDescription*>(content); - XmlElement* root = new XmlElement( - QName(kChromotingXmlNamespace, kDescriptionTag), true); - - const CandidateSessionConfig* config = desc->config(); - std::vector<ChannelConfig>::const_iterator it; - - for (it = config->control_configs().begin(); - it != config->control_configs().end(); ++it) { - root->AddElement(FormatChannelConfig(*it, kControlTag)); - } - - for (it = config->event_configs().begin(); - it != config->event_configs().end(); ++it) { - root->AddElement(FormatChannelConfig(*it, kEventTag)); - } - - for (it = config->video_configs().begin(); - it != config->video_configs().end(); ++it) { - root->AddElement(FormatChannelConfig(*it, kVideoTag)); - } - - XmlElement* resolution_tag = new XmlElement( - QName(kChromotingXmlNamespace, kResolutionTag)); - resolution_tag->AddAttr(QName(kDefaultNs, kWidthAttr), - base::IntToString( - config->initial_resolution().width)); - resolution_tag->AddAttr(QName(kDefaultNs, kHeightAttr), - base::IntToString( - config->initial_resolution().height)); - root->AddElement(resolution_tag); - - if (desc->certificate() || !desc->auth_token().empty()) { - XmlElement* authentication_tag = new XmlElement( - QName(kChromotingXmlNamespace, kAuthenticationTag)); - - if (desc->certificate()) { - XmlElement* certificate_tag = new XmlElement( - QName(kChromotingXmlNamespace, kCertificateTag)); - - std::string der_cert; - if (!desc->certificate()->GetDEREncoded(&der_cert)) { - LOG(DFATAL) << "Cannot obtain DER encoded certificate"; - } - - std::string base64_cert; - if (!base::Base64Encode(der_cert, &base64_cert)) { - LOG(DFATAL) << "Cannot perform base64 encode on certificate"; - } - - certificate_tag->SetBodyText(base64_cert); - authentication_tag->AddElement(certificate_tag); - } - - if (!desc->master_key().empty()) { - XmlElement* master_key_tag = new XmlElement( - QName(kChromotingXmlNamespace, kMasterKeyTag)); - - std::string master_key_base64; - if (!base::Base64Encode(desc->master_key(), &master_key_base64)) { - LOG(DFATAL) << "Cannot perform base64 encode on master key"; - } - - master_key_tag->SetBodyText(master_key_base64); - authentication_tag->AddElement(master_key_tag); - } - - if (!desc->auth_token().empty()) { - XmlElement* auth_token_tag = new XmlElement( - QName(kChromotingXmlNamespace, kAuthTokenTag)); - auth_token_tag->SetBodyText(desc->auth_token()); - authentication_tag->AddElement(auth_token_tag); - } - - root->AddElement(authentication_tag); - } - - *elem = root; + *elem = desc->ToXml(); return true; } diff --git a/remoting/protocol/jingle_session_manager.h b/remoting/protocol/jingle_session_manager.h index b91087f..eb6ca8b 100644 --- a/remoting/protocol/jingle_session_manager.h +++ b/remoting/protocol/jingle_session_manager.h @@ -10,11 +10,11 @@ #include "base/memory/ref_counted.h" #include "net/base/x509_certificate.h" +#include "remoting/protocol/content_description.h" #include "remoting/protocol/jingle_session.h" #include "remoting/protocol/session_manager.h" #include "third_party/libjingle/source/talk/p2p/base/session.h" #include "third_party/libjingle/source/talk/p2p/base/sessionclient.h" -#include "third_party/libjingle/source/talk/p2p/base/sessiondescription.h" class MessageLoop; @@ -27,45 +27,8 @@ class SessionManager; } // namespace cricket namespace remoting { - namespace protocol { -// ContentDescription used for chromoting sessions. It contains the information -// from the content description stanza in the session intialization handshake. -// -// This class also provides a type abstraction so that the Chromotocol Session -// interface does not need to depend on libjingle. -class ContentDescription : public cricket::ContentDescription { - public: - explicit ContentDescription(const CandidateSessionConfig* config, - const std::string& auth_token, - const std::string& master_key, - scoped_refptr<net::X509Certificate> certificate); - virtual ~ContentDescription(); - - const CandidateSessionConfig* config() const { - return candidate_config_.get(); - } - - const std::string& auth_token() const { return auth_token_; } - const std::string& master_key() const { return master_key_; } - scoped_refptr<net::X509Certificate> certificate() const { - return certificate_; - } - - private: - scoped_ptr<const CandidateSessionConfig> candidate_config_; - - // This may contain the initiating, or the accepting token depending on - // context. - std::string auth_token_; - - // Master key used for the session encrypted with the hosts key. - std::string master_key_; - - scoped_refptr<net::X509Certificate> certificate_; -}; - // This class implements SessionClient for Chromoting sessions. It acts as a // server that accepts chromoting connections and can also make new connections // to other hosts. @@ -160,7 +123,6 @@ class JingleSessionManager }; } // namespace protocol - } // namespace remoting #endif // REMOTING_PROTOCOL_JINGLE_SESSION_MANAGER_H_ diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index afb4a08..3561353 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -561,6 +561,8 @@ 'protocol/connection_to_client.h', 'protocol/connection_to_host.cc', 'protocol/connection_to_host.h', + 'protocol/content_description.cc', + 'protocol/content_description.h', 'protocol/host_control_sender.cc', 'protocol/host_control_sender.h', 'protocol/host_message_dispatcher.cc', |