OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/webrtc_transport.h" | 5 #include "remoting/protocol/webrtc_transport.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_split.h" | |
16 #include "base/strings/string_util.h" | |
15 #include "base/task_runner_util.h" | 17 #include "base/task_runner_util.h" |
16 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" |
17 #include "jingle/glue/thread_wrapper.h" | 19 #include "jingle/glue/thread_wrapper.h" |
18 #include "remoting/protocol/authenticator.h" | 20 #include "remoting/protocol/authenticator.h" |
19 #include "remoting/protocol/port_allocator_factory.h" | 21 #include "remoting/protocol/port_allocator_factory.h" |
20 #include "remoting/protocol/stream_message_pipe_adapter.h" | 22 #include "remoting/protocol/stream_message_pipe_adapter.h" |
21 #include "remoting/protocol/transport_context.h" | 23 #include "remoting/protocol/transport_context.h" |
22 #include "third_party/webrtc/api/test/fakeconstraints.h" | 24 #include "third_party/webrtc/api/test/fakeconstraints.h" |
23 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 25 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
24 #include "third_party/webrtc/modules/audio_device/include/fake_audio_device.h" | 26 #include "third_party/webrtc/modules/audio_device/include/fake_audio_device.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
38 | 40 |
39 // XML namespace for the transport elements. | 41 // XML namespace for the transport elements. |
40 const char kTransportNamespace[] = "google:remoting:webrtc"; | 42 const char kTransportNamespace[] = "google:remoting:webrtc"; |
41 | 43 |
42 #if !defined(NDEBUG) | 44 #if !defined(NDEBUG) |
43 // Command line switch used to disable signature verification. | 45 // Command line switch used to disable signature verification. |
44 // TODO(sergeyu): Remove this flag. | 46 // TODO(sergeyu): Remove this flag. |
45 const char kDisableAuthenticationSwitchName[] = "disable-authentication"; | 47 const char kDisableAuthenticationSwitchName[] = "disable-authentication"; |
46 #endif | 48 #endif |
47 | 49 |
50 // Normalizes the SDP message to make sure the text used for HMAC signatures | |
51 // verifications is the same that was signed on the sending side.This is | |
kelvinp
2016/03/31 01:09:38
Nit: missing space after .
Sergey Ulanov
2016/03/31 16:52:18
Done.
| |
52 // necessary because WebRTC generates SDP with CRLF line endings which are | |
53 // sometimes converted to LF after passing the signaling channel. | |
54 std::string NormalizeSessionDescription(const std::string& sdp) { | |
55 // Split SDP lines. The CR symbols is removed by the TRIM_WHITESPACE flag. | |
56 std::vector<std::string> lines = | |
57 SplitString(sdp, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | |
58 return base::JoinString(lines, "\n") + "\n"; | |
59 } | |
60 | |
48 // A webrtc::CreateSessionDescriptionObserver implementation used to receive the | 61 // A webrtc::CreateSessionDescriptionObserver implementation used to receive the |
49 // results of creating descriptions for this end of the PeerConnection. | 62 // results of creating descriptions for this end of the PeerConnection. |
50 class CreateSessionDescriptionObserver | 63 class CreateSessionDescriptionObserver |
51 : public webrtc::CreateSessionDescriptionObserver { | 64 : public webrtc::CreateSessionDescriptionObserver { |
52 public: | 65 public: |
53 typedef base::Callback<void( | 66 typedef base::Callback<void( |
54 scoped_ptr<webrtc::SessionDescriptionInterface> description, | 67 scoped_ptr<webrtc::SessionDescriptionInterface> description, |
55 const std::string& error)> ResultCallback; | 68 const std::string& error)> ResultCallback; |
56 | 69 |
57 static CreateSessionDescriptionObserver* Create( | 70 static CreateSessionDescriptionObserver* Create( |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 webrtc::PeerConnectionInterface::SignalingState expected_state = | 212 webrtc::PeerConnectionInterface::SignalingState expected_state = |
200 transport_context_->role() == TransportRole::CLIENT | 213 transport_context_->role() == TransportRole::CLIENT |
201 ? webrtc::PeerConnectionInterface::kStable | 214 ? webrtc::PeerConnectionInterface::kStable |
202 : webrtc::PeerConnectionInterface::kHaveLocalOffer; | 215 : webrtc::PeerConnectionInterface::kHaveLocalOffer; |
203 if (peer_connection_->signaling_state() != expected_state) { | 216 if (peer_connection_->signaling_state() != expected_state) { |
204 LOG(ERROR) << "Received unexpected WebRTC session_description."; | 217 LOG(ERROR) << "Received unexpected WebRTC session_description."; |
205 return false; | 218 return false; |
206 } | 219 } |
207 | 220 |
208 std::string type = session_description->Attr(QName(std::string(), "type")); | 221 std::string type = session_description->Attr(QName(std::string(), "type")); |
209 std::string sdp = session_description->BodyText(); | 222 std::string sdp = |
223 NormalizeSessionDescription(session_description->BodyText()); | |
210 if (type.empty() || sdp.empty()) { | 224 if (type.empty() || sdp.empty()) { |
211 LOG(ERROR) << "Incorrect session description format."; | 225 LOG(ERROR) << "Incorrect session description format."; |
212 return false; | 226 return false; |
213 } | 227 } |
214 | 228 |
215 std::string signature_base64 = | 229 std::string signature_base64 = |
216 session_description->Attr(QName(std::string(), "signature")); | 230 session_description->Attr(QName(std::string(), "signature")); |
217 std::string signature; | 231 std::string signature; |
218 if (!base::Base64Decode(signature_base64, &signature) || | 232 if (!base::Base64Decode(signature_base64, &signature) || |
219 !handshake_hmac_.Verify(sdp, signature)) { | 233 !handshake_hmac_.Verify(sdp, signature)) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 Close(CHANNEL_CONNECTION_ERROR); | 314 Close(CHANNEL_CONNECTION_ERROR); |
301 return; | 315 return; |
302 } | 316 } |
303 | 317 |
304 std::string description_sdp; | 318 std::string description_sdp; |
305 if (!description->ToString(&description_sdp)) { | 319 if (!description->ToString(&description_sdp)) { |
306 LOG(ERROR) << "Failed to serialize description."; | 320 LOG(ERROR) << "Failed to serialize description."; |
307 Close(CHANNEL_CONNECTION_ERROR); | 321 Close(CHANNEL_CONNECTION_ERROR); |
308 return; | 322 return; |
309 } | 323 } |
324 description_sdp = NormalizeSessionDescription(description_sdp); | |
310 | 325 |
311 // Format and send the session description to the peer. | 326 // Format and send the session description to the peer. |
312 scoped_ptr<XmlElement> transport_info( | 327 scoped_ptr<XmlElement> transport_info( |
313 new XmlElement(QName(kTransportNamespace, "transport"), true)); | 328 new XmlElement(QName(kTransportNamespace, "transport"), true)); |
314 XmlElement* offer_tag = | 329 XmlElement* offer_tag = |
315 new XmlElement(QName(kTransportNamespace, "session-description")); | 330 new XmlElement(QName(kTransportNamespace, "session-description")); |
316 transport_info->AddElement(offer_tag); | 331 transport_info->AddElement(offer_tag); |
317 offer_tag->SetAttr(QName(std::string(), "type"), description->type()); | 332 offer_tag->SetAttr(QName(std::string(), "type"), description->type()); |
318 offer_tag->SetBodyText(description_sdp); | 333 offer_tag->SetBodyText(description_sdp); |
319 | 334 |
320 std::string digest; | 335 std::string digest; |
321 digest.resize(handshake_hmac_.DigestLength()); | 336 digest.resize(handshake_hmac_.DigestLength()); |
322 CHECK(handshake_hmac_.Sign(description_sdp, | 337 CHECK(handshake_hmac_.Sign(description_sdp, |
323 reinterpret_cast<uint8_t*>(&(digest[0])), | 338 reinterpret_cast<uint8_t*>(&(digest[0])), |
324 digest.size())); | 339 digest.size())); |
325 std::string digest_base64; | 340 std::string digest_base64; |
326 base::Base64Encode(digest, &digest_base64); | 341 base::Base64Encode(digest, &digest_base64); |
327 offer_tag->SetAttr(QName(std::string(), "signature"), digest_base64); | 342 offer_tag->SetAttr(QName(std::string(), "signature"), digest_base64); |
328 | 343 |
329 send_transport_info_callback_.Run(std::move(transport_info)); | 344 send_transport_info_callback_.Run(std::move(transport_info)); |
330 | 345 |
331 peer_connection_->SetLocalDescription( | 346 peer_connection_->SetLocalDescription( |
332 SetSessionDescriptionObserver::Create(base::Bind( | 347 SetSessionDescriptionObserver::Create(base::Bind( |
333 &WebrtcTransport::OnLocalDescriptionSet, weak_factory_.GetWeakPtr())), | 348 &WebrtcTransport::OnLocalDescriptionSet, weak_factory_.GetWeakPtr())), |
334 description.release()); | 349 description.release()); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 peer_connection_->Close(); | 544 peer_connection_->Close(); |
530 peer_connection_ = nullptr; | 545 peer_connection_ = nullptr; |
531 peer_connection_factory_ = nullptr; | 546 peer_connection_factory_ = nullptr; |
532 | 547 |
533 if (error != OK) | 548 if (error != OK) |
534 event_handler_->OnWebrtcTransportError(error); | 549 event_handler_->OnWebrtcTransportError(error); |
535 } | 550 } |
536 | 551 |
537 } // namespace protocol | 552 } // namespace protocol |
538 } // namespace remoting | 553 } // namespace remoting |
OLD | NEW |