Bug 942367 - Part 2: DOMMediaStream support for PeerIdentity. r=bholley, r=roc
☠☠ backed out by c2094871202f ☠ ☠
authorMartin Thomson <martin.thomson@gmail.com>
Thu, 10 Apr 2014 11:51:29 -0700
changeset 197696 7d2138e87ca0d7617333a18137819b5ad6480855
parent 197695 7cc66aee4341db6523eeee2b10f6fa9e58a30ca6
child 197697 1e581e74878de5a0f8d2328a77f686b5d6ce89b2
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley, roc
bugs942367
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 942367 - Part 2: DOMMediaStream support for PeerIdentity. r=bholley, r=roc
content/media/DOMMediaStream.h
content/media/webrtc/PeerIdentity.cpp
content/media/webrtc/PeerIdentity.h
content/media/webrtc/moz.build
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -6,19 +6,20 @@
 #ifndef NSDOMMEDIASTREAM_H_
 #define NSDOMMEDIASTREAM_H_
 
 #include "nsIDOMMediaStream.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "StreamBuffer.h"
 #include "nsIDOMWindow.h"
+#include "nsIPrincipal.h"
+#include "mozilla/PeerIdentity.h"
 
 class nsXPCClassInfo;
-class nsIPrincipal;
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
 // currentTime getter.
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 // X11 has a #define for CurrentTime. Unbelievable :-(.
@@ -91,24 +92,42 @@ public:
   bool IsFinished();
   /**
    * Returns a principal indicating who may access this stream. The stream contents
    * can only be accessed by principals subsuming this principal.
    */
   nsIPrincipal* GetPrincipal() { return mPrincipal; }
 
   /**
+   * These are used in WebRTC.  A peerIdentity constrained MediaStream cannot be sent
+   * across the network to anything other than a peer with the provided identity.
+   * If this is set, then mPrincipal should be an instance of nsNullPrincipal.
+   */
+  PeerIdentity* GetPeerIdentity() const { return mPeerIdentity; }
+  void SetPeerIdentity(PeerIdentity* aPeerIdentity)
+  {
+    mPeerIdentity = aPeerIdentity;
+  }
+
+  /**
    * Indicate that data will be contributed to this stream from origin aPrincipal.
    * If aPrincipal is null, this is ignored. Otherwise, from now on the contents
    * of this stream can only be accessed by principals that subsume aPrincipal.
    * Returns true if the stream's principal changed.
    */
   bool CombineWithPrincipal(nsIPrincipal* aPrincipal);
 
   /**
+   * This is used in WebRTC to move from a protected state (nsNullPrincipal) to
+   * one where the stream is accessible to script.  Don't call this.
+   * CombineWithPrincipal is almost certainly more appropriate.
+   */
+  void SetPrincipal(nsIPrincipal* aPrincipal) { mPrincipal = aPrincipal; }
+
+  /**
    * Called when this stream's MediaStreamGraph has been shut down. Normally
    * MSGs are only shut down when all streams have been removed, so this
    * will only be called during a forced shutdown due to application exit.
    */
   void NotifyMediaStreamGraphShutdown();
   /**
    * Called when the main-thread state of the MediaStream changed.
    */
@@ -195,16 +214,19 @@ protected:
   nsCOMPtr<nsIDOMWindow> mWindow;
 
   // MediaStream is owned by the graph, but we tell it when to die, and it won't
   // die until we let it.
   MediaStream* mStream;
   // Principal identifying who may access the contents of this stream.
   // If null, this stream can be used by anyone because it has no content yet.
   nsCOMPtr<nsIPrincipal> mPrincipal;
+  // this is used in gUM and WebRTC to identify peers that this stream
+  // is allowed to be sent to
+  nsAutoPtr<PeerIdentity> mPeerIdentity;
 
   nsAutoTArray<nsRefPtr<MediaStreamTrack>,2> mTracks;
   nsRefPtr<StreamListener> mListener;
 
   nsTArray<nsAutoPtr<OnTracksAvailableCallback> > mRunOnTracksAvailable;
 
   // Keep these alive until the stream finishes
   nsTArray<nsCOMPtr<nsISupports> > mConsumersToKeepAlive;
new file mode 100644
--- /dev/null
+++ b/content/media/webrtc/PeerIdentity.cpp
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2 expandtab
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "PeerIdentity.h"
+
+#include "nsCOMPtr.h"
+#include "nsIIDNService.h"
+#include "nsNetCID.h"
+
+namespace mozilla {
+
+bool
+PeerIdentity::Equals(const PeerIdentity& aOther) const
+{
+  return Equals(aOther.mPeerIdentity);
+}
+
+bool
+PeerIdentity::Equals(const nsAString& aOtherString) const
+{
+  nsString user;
+  GetUser(mPeerIdentity, user);
+  nsString otherUser;
+  GetUser(aOtherString, otherUser);
+  if (user != otherUser) {
+    return false;
+  }
+
+  nsString host;
+  GetHost(mPeerIdentity, host);
+  nsString otherHost;
+  GetHost(aOtherString, otherHost);
+
+  nsresult rv;
+  nsCOMPtr<nsIIDNService> idnService
+    = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return host == otherHost;
+  }
+
+  nsCString normHost;
+  GetNormalizedHost(idnService, host, normHost);
+  nsCString normOtherHost;
+  GetNormalizedHost(idnService, otherHost, normOtherHost);
+  return normHost == normOtherHost;
+}
+
+/* static */ void
+PeerIdentity::GetUser(const nsAString& aPeerIdentity, nsAString& aUser)
+{
+  int32_t at = aPeerIdentity.FindChar('@');
+  if (at >= 0) {
+    aUser = Substring(aPeerIdentity, 0, at);
+  } else {
+    aUser.Truncate();
+  }
+}
+
+/* static */ void
+PeerIdentity::GetHost(const nsAString& aPeerIdentity, nsAString& aHost)
+{
+  int32_t at = aPeerIdentity.FindChar('@');
+  if (at >= 0) {
+    aHost = Substring(aPeerIdentity, at + 1);
+  } else {
+    aHost = aPeerIdentity;
+  }
+}
+
+/* static */ void
+PeerIdentity::GetNormalizedHost(const nsCOMPtr<nsIIDNService>& aIdnService,
+                                const nsAString& aHost,
+                                nsACString& aNormalizedHost)
+{
+  nsCString chost = NS_ConvertUTF16toUTF8(aHost);
+  nsresult rv = aIdnService->ConvertUTF8toACE(chost, aNormalizedHost);
+  NS_WARN_IF(NS_FAILED(rv));
+}
+
+} /* namespace mozilla */
new file mode 100644
--- /dev/null
+++ b/content/media/webrtc/PeerIdentity.h
@@ -0,0 +1,79 @@
+ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+  * vim: sw=2 ts=2 sts=2 expandtab
+  * This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef PeerIdentity_h
+#define PeerIdentity_h
+
+#ifdef MOZILLA_INTERNAL_API
+#include "nsString.h"
+#else
+#include "nsStringAPI.h"
+#endif
+
+template <class T> class nsCOMPtr;
+class nsIIDNService;
+
+namespace mozilla {
+
+/**
+ * This class implements the identifier used in WebRTC identity.  Peers are
+ * identified using a string in the form [<user>@]<domain>, for instance,
+ * "user@example.com'. The (optional) user portion is a site-controlled string
+ * containing any character other than '@'.  The domain portion is a valid IDN
+ * domain name and is compared accordingly.
+ *
+ * See: http://tools.ietf.org/html/draft-ietf-rtcweb-security-arch-09#section-5.6.5.3.3.1
+ */
+class PeerIdentity MOZ_FINAL
+{
+public:
+  PeerIdentity(const nsAString& aPeerIdentity)
+    : mPeerIdentity(aPeerIdentity) {}
+  ~PeerIdentity() {}
+
+  bool Equals(const PeerIdentity& aOther) const;
+  bool Equals(const nsAString& aOtherString) const;
+  const nsString& ToString() const { return mPeerIdentity; }
+
+private:
+  static void GetUser(const nsAString& aPeerIdentity, nsAString& aUser);
+  static void GetHost(const nsAString& aPeerIdentity, nsAString& aHost);
+
+  static void GetNormalizedHost(const nsCOMPtr<nsIIDNService>& aIdnService,
+                                const nsAString& aHost,
+                                nsACString& aNormalizedHost);
+
+  nsString mPeerIdentity;
+};
+
+inline bool
+operator==(const PeerIdentity& aOne, const PeerIdentity& aTwo)
+{
+  return aOne.Equals(aTwo);
+}
+
+inline bool
+operator==(const PeerIdentity& aOne, const nsAString& aString)
+{
+  return aOne.Equals(aString);
+}
+
+inline bool
+operator!=(const PeerIdentity& aOne, const PeerIdentity& aTwo)
+{
+  return !aOne.Equals(aTwo);
+}
+
+inline bool
+operator!=(const PeerIdentity& aOne, const nsAString& aString)
+{
+  return !aOne.Equals(aString);
+}
+
+
+} /* namespace mozilla */
+
+#endif /* PeerIdentity_h */
--- a/content/media/webrtc/moz.build
+++ b/content/media/webrtc/moz.build
@@ -42,15 +42,20 @@ if CONFIG['MOZ_WEBRTC']:
     ]
 
 XPIDL_SOURCES += [
     'nsITabSource.idl'
 ]
 
 UNIFIED_SOURCES += [
     'MediaEngineDefault.cpp',
+    'PeerIdentity.cpp',
+]
+
+EXPORTS.mozilla += [
+    'PeerIdentity.h',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'gklayout'
 if CONFIG['OS_ARCH'] == 'WINNT':
     DEFINES['NOMINMAX'] = True