Bug 1024098, Add some helpers for principal verification with PBackground. r=mrbkap.
authorBen Turner <bent.mozilla@gmail.com>
Mon, 07 Jul 2014 11:13:04 -0700
changeset 192763 778627b321e98aa5fcf81f72c5bc2f034271ebf8
parent 192762 4d02030db21b6553d7de66febaf11a1822b11a02
child 192764 8face5cf2b8d25346bf8ace2c40d5b600f49150a
push id7651
push usercbook@mozilla.com
push dateTue, 08 Jul 2014 13:28:32 +0000
treeherderfx-team@05cfda67b9db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs1024098
milestone33.0a1
Bug 1024098, Add some helpers for principal verification with PBackground. r=mrbkap.
ipc/glue/BackgroundUtils.cpp
ipc/glue/BackgroundUtils.h
ipc/glue/PBackgroundSharedTypes.ipdlh
ipc/glue/moz.build
new file mode 100644
--- /dev/null
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -0,0 +1,155 @@
+/* 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 "BackgroundUtils.h"
+
+#include "MainThreadUtils.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/ipc/PBackgroundSharedTypes.h"
+#include "nsIPrincipal.h"
+#include "nsIScriptSecurityManager.h"
+#include "nsIURI.h"
+#include "nsNetUtil.h"
+#include "nsNullPrincipal.h"
+#include "nsServiceManagerUtils.h"
+#include "nsString.h"
+
+namespace mozilla {
+namespace ipc {
+
+already_AddRefed<nsIPrincipal>
+PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo,
+                         nsresult* aOptionalResult)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aPrincipalInfo.type() != PrincipalInfo::T__None);
+
+  nsresult stackResult;
+  nsresult& rv = aOptionalResult ? *aOptionalResult : stackResult;
+
+  nsCOMPtr<nsIScriptSecurityManager> secMan =
+    do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIPrincipal> principal;
+
+  switch (aPrincipalInfo.type()) {
+    case PrincipalInfo::TSystemPrincipalInfo: {
+      rv = secMan->GetSystemPrincipal(getter_AddRefs(principal));
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return nullptr;
+      }
+
+      return principal.forget();
+    }
+
+    case PrincipalInfo::TNullPrincipalInfo: {
+      principal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID, &rv);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return nullptr;
+      }
+
+      return principal.forget();
+    }
+
+    case PrincipalInfo::TContentPrincipalInfo: {
+      const ContentPrincipalInfo& info =
+        aPrincipalInfo.get_ContentPrincipalInfo();
+
+      nsCOMPtr<nsIURI> uri;
+      rv = NS_NewURI(getter_AddRefs(uri), info.spec());
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return nullptr;
+      }
+
+      if (info.appId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
+        rv = secMan->GetSimpleCodebasePrincipal(uri, getter_AddRefs(principal));
+      } else {
+        rv = secMan->GetAppCodebasePrincipal(uri,
+                                             info.appId(),
+                                             info.isInBrowserElement(),
+                                             getter_AddRefs(principal));
+      }
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return nullptr;
+      }
+
+      return principal.forget();
+    }
+
+    default:
+      MOZ_CRASH("Unknown PrincipalInfo type!");
+  }
+
+  MOZ_CRASH("Should never get here!");
+}
+
+nsresult
+PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
+                         PrincipalInfo* aPrincipalInfo)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aPrincipal);
+  MOZ_ASSERT(aPrincipalInfo);
+
+  bool isNullPointer;
+  nsresult rv = aPrincipal->GetIsNullPrincipal(&isNullPointer);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (isNullPointer) {
+    *aPrincipalInfo = NullPrincipalInfo();
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIScriptSecurityManager> secMan =
+    do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  bool isSystemPrincipal;
+  rv = secMan->IsSystemPrincipal(aPrincipal, &isSystemPrincipal);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (isSystemPrincipal) {
+    *aPrincipalInfo = SystemPrincipalInfo();
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIURI> uri;
+  rv = aPrincipal->GetURI(getter_AddRefs(uri));
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  nsCString spec;
+  rv = uri->GetSpec(spec);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  uint32_t appId;
+  rv = aPrincipal->GetAppId(&appId);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  bool isInBrowserElement;
+  rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  *aPrincipalInfo = ContentPrincipalInfo(appId, isInBrowserElement, spec);
+  return NS_OK;
+}
+
+} // namespace ipc
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/glue/BackgroundUtils.h
@@ -0,0 +1,40 @@
+/* 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 mozilla_ipc_backgroundutils_h__
+#define mozilla_ipc_backgroundutils_h__
+
+#include "mozilla/Attributes.h"
+#include "nsCOMPtr.h"
+#include "nscore.h"
+
+class nsIPrincipal;
+
+namespace mozilla {
+namespace ipc {
+
+class PrincipalInfo;
+
+/**
+ * Convert a PrincipalInfo to an nsIPrincipal.
+ *
+ * MUST be called on the main thread only.
+ */
+already_AddRefed<nsIPrincipal>
+PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo,
+                         nsresult* aOptionalResult = nullptr);
+
+/**
+ * Convert an nsIPrincipal to a PrincipalInfo.
+ *
+ * MUST be called on the main thread only.
+ */
+nsresult
+PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
+                         PrincipalInfo* aPrincipalInfo);
+
+} // namespace ipc
+} // namespace mozilla
+
+#endif // mozilla_ipc_backgroundutils_h__
new file mode 100644
--- /dev/null
+++ b/ipc/glue/PBackgroundSharedTypes.ipdlh
@@ -0,0 +1,29 @@
+/* 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/. */
+
+namespace mozilla {
+namespace ipc {
+
+struct ContentPrincipalInfo
+{
+  uint32_t appId;
+  bool isInBrowserElement;
+  nsCString spec;
+};
+
+struct SystemPrincipalInfo
+{ };
+
+struct NullPrincipalInfo
+{ };
+
+union PrincipalInfo
+{
+  ContentPrincipalInfo;
+  SystemPrincipalInfo;
+  NullPrincipalInfo;
+};
+
+} // namespace ipc
+} // namespace mozilla
--- a/ipc/glue/moz.build
+++ b/ipc/glue/moz.build
@@ -8,16 +8,17 @@ EXPORTS += [
     'nsIIPCBackgroundChildCreateCallback.h',
     'nsIIPCSerializableInputStream.h',
     'nsIIPCSerializableURI.h',
 ]
 
 EXPORTS.mozilla.ipc += [
     'BackgroundChild.h',
     'BackgroundParent.h',
+    'BackgroundUtils.h',
     'BrowserProcessSubThread.h',
     'CrossProcessMutex.h',
     'FileDescriptor.h',
     'FileDescriptorUtils.h',
     'GeckoChildProcessHost.h',
     'InputStreamUtils.h',
     'IOThreadChild.h',
     'MessageChannel.h',
@@ -90,16 +91,17 @@ else:
     ]
 
 EXPORTS.ipc += [
     'IPCMessageUtils.h',
 ]
 
 UNIFIED_SOURCES += [
     'BackgroundImpl.cpp',
+    'BackgroundUtils.cpp',
     'BrowserProcessSubThread.cpp',
     'FileDescriptor.cpp',
     'FileDescriptorUtils.cpp',
     'InputStreamUtils.cpp',
     'MessageChannel.cpp',
     'MessageLink.cpp',
     'MessagePump.cpp',
     'ProcessChild.cpp',
@@ -121,16 +123,17 @@ SOURCES += [
 
 LOCAL_INCLUDES += [
     '/xpcom/build',
 ]
 
 IPDL_SOURCES = [
     'InputStreamParams.ipdlh',
     'PBackground.ipdl',
+    'PBackgroundSharedTypes.ipdlh',
     'PBackgroundTest.ipdl',
     'ProtocolTypes.ipdlh',
     'URIParams.ipdlh',
 ]
 
 
 LOCAL_INCLUDES += [
     '/xpcom/threads',