зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1382883 - Pass paths and open file handles to CDM host binaries on CDM startup. r=gerald
MozReview-Commit-ID: 9IhRqlFrNJf --HG-- extra : source : de04ea0a90ae935bbc1d0f730332b034b5514f17 extra : intermediate-source : b18daff94ad3d832fcbd601d219c6db2eae46f90
This commit is contained in:
Родитель
93ac0cd0e3
Коммит
0637427899
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "ChromiumCDMAdapter.h"
|
#include "ChromiumCDMAdapter.h"
|
||||||
#include "content_decryption_module.h"
|
#include "content_decryption_module.h"
|
||||||
|
#include "content_decryption_module_ext.h"
|
||||||
#include "VideoUtils.h"
|
#include "VideoUtils.h"
|
||||||
#include "gmp-api/gmp-entrypoints.h"
|
#include "gmp-api/gmp-entrypoints.h"
|
||||||
#include "gmp-api/gmp-decryption.h"
|
#include "gmp-api/gmp-decryption.h"
|
||||||
|
@ -12,12 +13,25 @@
|
||||||
#include "gmp-api/gmp-platform.h"
|
#include "gmp-api/gmp-platform.h"
|
||||||
#include "WidevineUtils.h"
|
#include "WidevineUtils.h"
|
||||||
#include "GMPLog.h"
|
#include "GMPLog.h"
|
||||||
|
#include "mozilla/Move.h"
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX) || defined(XP_LINUX)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Declared in WidevineAdapter.cpp.
|
// Declared in WidevineAdapter.cpp.
|
||||||
extern const GMPPlatformAPI* sPlatform;
|
extern const GMPPlatformAPI* sPlatform;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
ChromiumCDMAdapter::ChromiumCDMAdapter(nsTArray<nsCString>&& aHostFilePaths)
|
||||||
|
{
|
||||||
|
PopulateHostFiles(Move(aHostFilePaths));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ChromiumCDMAdapter::SetAdaptee(PRLibrary* aLib)
|
ChromiumCDMAdapter::SetAdaptee(PRLibrary* aLib)
|
||||||
{
|
{
|
||||||
|
@ -37,6 +51,14 @@ ChromiumCdmHost(int aHostInterfaceVersion, void* aUserData)
|
||||||
#define STRINGIFY(s) _STRINGIFY(s)
|
#define STRINGIFY(s) _STRINGIFY(s)
|
||||||
#define _STRINGIFY(s) #s
|
#define _STRINGIFY(s) #s
|
||||||
|
|
||||||
|
static cdm::HostFile
|
||||||
|
TakeToCDMHostFile(HostFileData& aHostFileData)
|
||||||
|
{
|
||||||
|
return cdm::HostFile(aHostFileData.mBinary.Path().get(),
|
||||||
|
aHostFileData.mBinary.TakePlatformFile(),
|
||||||
|
aHostFileData.mSig.TakePlatformFile());
|
||||||
|
}
|
||||||
|
|
||||||
GMPErr
|
GMPErr
|
||||||
ChromiumCDMAdapter::GMPInit(const GMPPlatformAPI* aPlatformAPI)
|
ChromiumCDMAdapter::GMPInit(const GMPPlatformAPI* aPlatformAPI)
|
||||||
{
|
{
|
||||||
|
@ -46,6 +68,19 @@ ChromiumCDMAdapter::GMPInit(const GMPPlatformAPI* aPlatformAPI)
|
||||||
return GMPGenericErr;
|
return GMPGenericErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: we must call the VerifyCdmHost_0 function if it's present before
|
||||||
|
// we call the initialize function.
|
||||||
|
auto verify = reinterpret_cast<decltype(::VerifyCdmHost_0)*>(
|
||||||
|
PR_FindFunctionSymbol(mLib, STRINGIFY(VerifyCdmHost_0)));
|
||||||
|
if (verify) {
|
||||||
|
nsTArray<cdm::HostFile> files;
|
||||||
|
for (HostFileData& hostFile : mHostFiles) {
|
||||||
|
files.AppendElement(TakeToCDMHostFile(hostFile));
|
||||||
|
}
|
||||||
|
bool result = verify(files.Elements(), files.Length());
|
||||||
|
GMP_LOG("%s VerifyCdmHost_0 returned %d", __func__, result);
|
||||||
|
}
|
||||||
|
|
||||||
auto init = reinterpret_cast<decltype(::INITIALIZE_CDM_MODULE)*>(
|
auto init = reinterpret_cast<decltype(::INITIALIZE_CDM_MODULE)*>(
|
||||||
PR_FindFunctionSymbol(mLib, STRINGIFY(INITIALIZE_CDM_MODULE)));
|
PR_FindFunctionSymbol(mLib, STRINGIFY(INITIALIZE_CDM_MODULE)));
|
||||||
if (!init) {
|
if (!init) {
|
||||||
|
@ -130,4 +165,64 @@ ChromiumCDMAdapter::Supports(int32_t aModuleVersion,
|
||||||
aHostVersion == cdm::Host_8::kVersion;
|
aHostVersion == cdm::Host_8::kVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HostFile::HostFile(HostFile&& aOther)
|
||||||
|
: mPath(aOther.mPath)
|
||||||
|
, mFile(aOther.TakePlatformFile())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HostFile::~HostFile()
|
||||||
|
{
|
||||||
|
if (mFile != cdm::kInvalidPlatformFile) {
|
||||||
|
#ifdef XP_WIN
|
||||||
|
CloseHandle(mFile);
|
||||||
|
#else
|
||||||
|
close(mFile);
|
||||||
|
#endif
|
||||||
|
mFile = cdm::kInvalidPlatformFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
HostFile::HostFile(const nsCString& aPath)
|
||||||
|
: mPath(NS_ConvertUTF8toUTF16(aPath))
|
||||||
|
{
|
||||||
|
HANDLE handle = CreateFileW(mPath.get(),
|
||||||
|
GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
mFile = (handle == INVALID_HANDLE_VALUE) ? cdm::kInvalidPlatformFile : handle;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX) || defined(XP_LINUX)
|
||||||
|
HostFile::HostFile(const nsCString& aPath)
|
||||||
|
: mPath(aPath)
|
||||||
|
{
|
||||||
|
// Note: open() returns -1 on failure; i.e. kInvalidPlatformFile.
|
||||||
|
mFile = open(aPath.get(), O_RDONLY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cdm::PlatformFile
|
||||||
|
HostFile::TakePlatformFile()
|
||||||
|
{
|
||||||
|
cdm::PlatformFile f = mFile;
|
||||||
|
mFile = cdm::kInvalidPlatformFile;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ChromiumCDMAdapter::PopulateHostFiles(nsTArray<nsCString>&& aHostFilePaths)
|
||||||
|
{
|
||||||
|
for (const nsCString& path : aHostFilePaths) {
|
||||||
|
mHostFiles.AppendElement(
|
||||||
|
HostFileData(mozilla::HostFile(path),
|
||||||
|
mozilla::HostFile(path + NS_LITERAL_CSTRING(".sig"))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -9,14 +9,59 @@
|
||||||
#include "GMPLoader.h"
|
#include "GMPLoader.h"
|
||||||
#include "prlink.h"
|
#include "prlink.h"
|
||||||
#include "GMPUtils.h"
|
#include "GMPUtils.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
#include "content_decryption_module_ext.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
struct GMPPlatformAPI;
|
struct GMPPlatformAPI;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
typedef nsString HostFileString;
|
||||||
|
#else
|
||||||
|
typedef nsCString HostFileString;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class HostFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit HostFile(const nsCString& aPath);
|
||||||
|
HostFile(HostFile&& aOther);
|
||||||
|
~HostFile();
|
||||||
|
|
||||||
|
const HostFileString& Path() const { return mPath; }
|
||||||
|
cdm::PlatformFile TakePlatformFile();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const HostFileString mPath;
|
||||||
|
cdm::PlatformFile mFile = cdm::kInvalidPlatformFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HostFileData
|
||||||
|
{
|
||||||
|
HostFileData(HostFile&& aBinary, HostFile&& aSig)
|
||||||
|
: mBinary(Move(aBinary))
|
||||||
|
, mSig(Move(aSig))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HostFileData(HostFileData&& aOther)
|
||||||
|
: mBinary(Move(aOther.mBinary))
|
||||||
|
, mSig(Move(aOther.mSig))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~HostFileData() {}
|
||||||
|
|
||||||
|
HostFile mBinary;
|
||||||
|
HostFile mSig;
|
||||||
|
};
|
||||||
|
|
||||||
class ChromiumCDMAdapter : public gmp::GMPAdapter
|
class ChromiumCDMAdapter : public gmp::GMPAdapter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
explicit ChromiumCDMAdapter(nsTArray<nsCString>&& aHostFilePaths);
|
||||||
|
|
||||||
void SetAdaptee(PRLibrary* aLib) override;
|
void SetAdaptee(PRLibrary* aLib) override;
|
||||||
|
|
||||||
|
@ -33,7 +78,10 @@ public:
|
||||||
int32_t aHostVersion);
|
int32_t aHostVersion);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void PopulateHostFiles(nsTArray<nsCString>&& aHostFilePaths);
|
||||||
|
|
||||||
PRLibrary* mLib = nullptr;
|
PRLibrary* mLib = nullptr;
|
||||||
|
nsTArray<HostFileData> mHostFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -22,13 +22,16 @@
|
||||||
#include "GMPUtils.h"
|
#include "GMPUtils.h"
|
||||||
#include "prio.h"
|
#include "prio.h"
|
||||||
#include "base/task.h"
|
#include "base/task.h"
|
||||||
|
#include "base/command_line.h"
|
||||||
#include "widevine-adapter/WidevineAdapter.h"
|
#include "widevine-adapter/WidevineAdapter.h"
|
||||||
#include "ChromiumCDMAdapter.h"
|
#include "ChromiumCDMAdapter.h"
|
||||||
|
#include "GMPLog.h"
|
||||||
|
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#include <stdlib.h> // for _exit()
|
#include <stdlib.h> // for _exit()
|
||||||
|
#include "WinUtils.h"
|
||||||
#else
|
#else
|
||||||
#include <unistd.h> // for _exit()
|
#include <unistd.h> // for _exit()
|
||||||
#endif
|
#endif
|
||||||
|
@ -118,7 +121,6 @@ GetPluginFile(const nsAString& aPluginPath,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(XP_MACOSX) || !defined(MOZ_GMP_SANDBOX)
|
|
||||||
static bool
|
static bool
|
||||||
GetPluginFile(const nsAString& aPluginPath,
|
GetPluginFile(const nsAString& aPluginPath,
|
||||||
nsCOMPtr<nsIFile>& aLibFile)
|
nsCOMPtr<nsIFile>& aLibFile)
|
||||||
|
@ -126,7 +128,6 @@ GetPluginFile(const nsAString& aPluginPath,
|
||||||
nsCOMPtr<nsIFile> unusedlibDir;
|
nsCOMPtr<nsIFile> unusedlibDir;
|
||||||
return GetPluginFile(aPluginPath, unusedlibDir, aLibFile);
|
return GetPluginFile(aPluginPath, unusedlibDir, aLibFile);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
|
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
|
||||||
static nsCString
|
static nsCString
|
||||||
|
@ -296,6 +297,25 @@ GMPChild::RecvPreloadLibs(const nsCString& aLibs)
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GMPChild::ResolveLinks(nsCOMPtr<nsIFile>& aPath)
|
||||||
|
{
|
||||||
|
#if defined(XP_WIN)
|
||||||
|
return widget::WinUtils::ResolveJunctionPointsAndSymLinks(aPath);
|
||||||
|
#elif defined(XP_MACOSX)
|
||||||
|
nsCString targetPath = GetNativeTarget(aPath);
|
||||||
|
nsCOMPtr<nsIFile> newFile;
|
||||||
|
if (NS_FAILED(
|
||||||
|
NS_NewNativeLocalFile(targetPath, true, getter_AddRefs(newFile)))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
aPath = newFile;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GMPChild::GetUTF8LibPath(nsACString& aOutLibPath)
|
GMPChild::GetUTF8LibPath(nsACString& aOutLibPath)
|
||||||
{
|
{
|
||||||
|
@ -325,6 +345,117 @@ GMPChild::GetUTF8LibPath(nsACString& aOutLibPath)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
#define FIREFOX_FILE NS_LITERAL_STRING("firefox")
|
||||||
|
#define XUL_LIB_FILE NS_LITERAL_STRING("XUL")
|
||||||
|
#elif defined(XP_LINUX)
|
||||||
|
#define FIREFOX_FILE NS_LITERAL_STRING("firefox")
|
||||||
|
#define XUL_LIB_FILE NS_LITERAL_STRING("libxul.so")
|
||||||
|
#elif defined(OS_WIN)
|
||||||
|
#define FIREFOX_FILE NS_LITERAL_STRING("firefox.exe")
|
||||||
|
#define XUL_LIB_FILE NS_LITERAL_STRING("xul.dll")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
static bool
|
||||||
|
GetFirefoxAppPath(nsCOMPtr<nsIFile> aPluginContainerPath,
|
||||||
|
nsCOMPtr<nsIFile>& aOutFirefoxAppPath)
|
||||||
|
{
|
||||||
|
// aPluginContainerPath will end with something like:
|
||||||
|
// xxxx/NightlyDebug.app/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container
|
||||||
|
MOZ_ASSERT(aPluginContainerPath);
|
||||||
|
nsCOMPtr<nsIFile> path = aPluginContainerPath;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
nsCOMPtr<nsIFile> parent;
|
||||||
|
if (NS_FAILED(path->GetParent(getter_AddRefs(parent)))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
path = parent;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(path);
|
||||||
|
aOutFirefoxAppPath = path;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsTArray<nsCString>
|
||||||
|
GMPChild::MakeCDMHostVerificationPaths()
|
||||||
|
{
|
||||||
|
nsTArray<nsCString> paths;
|
||||||
|
|
||||||
|
// Plugin binary path.
|
||||||
|
nsCOMPtr<nsIFile> path;
|
||||||
|
nsString str;
|
||||||
|
if (GetPluginFile(mPluginPath, path) && FileExists(path) &&
|
||||||
|
ResolveLinks(path) && NS_SUCCEEDED(path->GetPath(str))) {
|
||||||
|
paths.AppendElement(NS_ConvertUTF16toUTF8(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plugin-container binary path.
|
||||||
|
// Note: clang won't let us initialize an nsString from a wstring, so we
|
||||||
|
// need to go through UTF8 to get to an nsString.
|
||||||
|
const std::string pluginContainer =
|
||||||
|
WideToUTF8(CommandLine::ForCurrentProcess()->program());
|
||||||
|
path = nullptr;
|
||||||
|
str = NS_ConvertUTF8toUTF16(nsDependentCString(pluginContainer.c_str()));
|
||||||
|
if (NS_SUCCEEDED(NS_NewLocalFile(str,
|
||||||
|
true, /* aFollowLinks */
|
||||||
|
getter_AddRefs(path))) &&
|
||||||
|
FileExists(path) && ResolveLinks(path) &&
|
||||||
|
NS_SUCCEEDED(path->GetPath(str))) {
|
||||||
|
paths.AppendElement(nsCString(NS_ConvertUTF16toUTF8(str)));
|
||||||
|
} else {
|
||||||
|
// Without successfully determining plugin-container's path, we can't
|
||||||
|
// determine libxul's or Firefox's. So give up.
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Firefox application binary path.
|
||||||
|
nsCOMPtr<nsIFile> appDir;
|
||||||
|
#if defined(XP_WIN) || defined(XP_LINUX)
|
||||||
|
// Note: re-using 'path' var here, as on Windows/Linux we assume Firefox
|
||||||
|
// executable is in the same directory as plugin-container.
|
||||||
|
if (NS_SUCCEEDED(path->GetParent(getter_AddRefs(appDir))) &&
|
||||||
|
NS_SUCCEEDED(appDir->Clone(getter_AddRefs(path))) &&
|
||||||
|
NS_SUCCEEDED(path->Append(FIREFOX_FILE)) && FileExists(path) &&
|
||||||
|
ResolveLinks(path) && NS_SUCCEEDED(path->GetPath(str))) {
|
||||||
|
paths.AppendElement(NS_ConvertUTF16toUTF8(str));
|
||||||
|
}
|
||||||
|
#elif defined(XP_MACOSX)
|
||||||
|
// On MacOS the firefox binary is a few parent directories up from
|
||||||
|
// plugin-container.
|
||||||
|
if (GetFirefoxAppPath(path, appDir) &&
|
||||||
|
NS_SUCCEEDED(appDir->Clone(getter_AddRefs(path))) &&
|
||||||
|
NS_SUCCEEDED(path->Append(FIREFOX_FILE)) && FileExists(path) &&
|
||||||
|
ResolveLinks(path) && NS_SUCCEEDED(path->GetPath(str))) {
|
||||||
|
paths.AppendElement(NS_ConvertUTF16toUTF8(str));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Libxul path. Note: re-using 'path' var here, as we assume libxul is in
|
||||||
|
// the same directory as Firefox executable.
|
||||||
|
appDir->GetPath(str);
|
||||||
|
if (NS_SUCCEEDED(appDir->Clone(getter_AddRefs(path))) &&
|
||||||
|
NS_SUCCEEDED(path->Append(XUL_LIB_FILE)) && FileExists(path) &&
|
||||||
|
ResolveLinks(path) && NS_SUCCEEDED(path->GetPath(str))) {
|
||||||
|
paths.AppendElement(NS_ConvertUTF16toUTF8(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsCString
|
||||||
|
ToCString(const nsTArray<nsCString>& aStrings)
|
||||||
|
{
|
||||||
|
nsCString result;
|
||||||
|
for (const nsCString& s : aStrings) {
|
||||||
|
if (!result.IsEmpty()) {
|
||||||
|
result.AppendLiteral(",");
|
||||||
|
}
|
||||||
|
result.Append(s);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
mozilla::ipc::IPCResult
|
mozilla::ipc::IPCResult
|
||||||
GMPChild::AnswerStartPlugin(const nsString& aAdapter)
|
GMPChild::AnswerStartPlugin(const nsString& aAdapter)
|
||||||
{
|
{
|
||||||
|
@ -365,7 +496,9 @@ GMPChild::AnswerStartPlugin(const nsString& aAdapter)
|
||||||
if (isWidevine) {
|
if (isWidevine) {
|
||||||
adapter = new WidevineAdapter();
|
adapter = new WidevineAdapter();
|
||||||
} else if (isChromium) {
|
} else if (isChromium) {
|
||||||
adapter = new ChromiumCDMAdapter();
|
nsTArray<nsCString> paths(MakeCDMHostVerificationPaths());
|
||||||
|
GMP_LOG("%s CDM host paths=%s", __func__, ToCString(paths).get());
|
||||||
|
adapter = new ChromiumCDMAdapter(Move(paths));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mGMPLoader->Load(libPath.get(),
|
if (!mGMPLoader->Load(libPath.get(),
|
||||||
|
|
|
@ -41,6 +41,8 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class GMPContentChild;
|
friend class GMPContentChild;
|
||||||
|
|
||||||
|
bool ResolveLinks(nsCOMPtr<nsIFile>& aPath);
|
||||||
|
|
||||||
bool GetUTF8LibPath(nsACString& aOutLibPath);
|
bool GetUTF8LibPath(nsACString& aOutLibPath);
|
||||||
|
|
||||||
mozilla::ipc::IPCResult AnswerStartPlugin(const nsString& aAdapter) override;
|
mozilla::ipc::IPCResult AnswerStartPlugin(const nsString& aAdapter) override;
|
||||||
|
@ -64,6 +66,8 @@ private:
|
||||||
|
|
||||||
GMPErr GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI, uint32_t aDecryptorId = 0);
|
GMPErr GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI, uint32_t aDecryptorId = 0);
|
||||||
|
|
||||||
|
nsTArray<nsCString> MakeCDMHostVerificationPaths();
|
||||||
|
|
||||||
nsTArray<UniquePtr<GMPContentChild>> mGMPContentChildren;
|
nsTArray<UniquePtr<GMPContentChild>> mGMPContentChildren;
|
||||||
|
|
||||||
RefPtr<GMPTimerChild> mTimerChild;
|
RefPtr<GMPTimerChild> mTimerChild;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ClearKeyCDM.h"
|
#include "ClearKeyCDM.h"
|
||||||
#include "ClearKeySessionManager.h"
|
#include "ClearKeySessionManager.h"
|
||||||
|
@ -24,6 +25,13 @@
|
||||||
// on Unix systems.
|
// on Unix systems.
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
#include "content_decryption_module.h"
|
#include "content_decryption_module.h"
|
||||||
|
#include "content_decryption_module_ext.h"
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX) || defined(XP_LINUX)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_WMF
|
#ifdef ENABLE_WMF
|
||||||
#include "WMFUtils.h"
|
#include "WMFUtils.h"
|
||||||
|
@ -36,6 +44,8 @@ void INITIALIZE_CDM_MODULE() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sCanReadHostVerificationFiles = false;
|
||||||
|
|
||||||
CDM_API
|
CDM_API
|
||||||
void* CreateCdmInstance(int cdm_interface_version,
|
void* CreateCdmInstance(int cdm_interface_version,
|
||||||
const char* key_system,
|
const char* key_system,
|
||||||
|
@ -53,6 +63,11 @@ void* CreateCdmInstance(int cdm_interface_version,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Test that we're able to read the host files.
|
||||||
|
if (!sCanReadHostVerificationFiles) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
cdm::Host_8* host = static_cast<cdm::Host_8*>(
|
cdm::Host_8* host = static_cast<cdm::Host_8*>(
|
||||||
get_cdm_host_func(cdm_interface_version, user_data));
|
get_cdm_host_func(cdm_interface_version, user_data));
|
||||||
ClearKeyCDM* clearKey = new ClearKeyCDM(host);
|
ClearKeyCDM* clearKey = new ClearKeyCDM(host);
|
||||||
|
@ -61,4 +76,57 @@ void* CreateCdmInstance(int cdm_interface_version,
|
||||||
|
|
||||||
return clearKey;
|
return clearKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t TEST_READ_SIZE = 16 * 1024;
|
||||||
|
|
||||||
|
bool
|
||||||
|
CanReadSome(cdm::PlatformFile aFile)
|
||||||
|
{
|
||||||
|
vector<uint8_t> data;
|
||||||
|
data.resize(TEST_READ_SIZE);
|
||||||
|
#ifdef XP_WIN
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
return ReadFile(aFile, &data.front(), TEST_READ_SIZE, &bytesRead, nullptr) &&
|
||||||
|
bytesRead > 0;
|
||||||
|
#elif defined(XP_MACOSX) || defined(XP_LINUX)
|
||||||
|
return read(aFile, &data.front(), TEST_READ_SIZE) > 0;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ClosePlatformFile(cdm::PlatformFile aFile)
|
||||||
|
{
|
||||||
|
#ifdef XP_WIN
|
||||||
|
CloseHandle(aFile);
|
||||||
|
#elif defined(XP_MACOSX) || defined(XP_LINUX)
|
||||||
|
close(aFile);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CDM_API
|
||||||
|
bool
|
||||||
|
VerifyCdmHost_0(const cdm::HostFile* aHostFiles, uint32_t aNumFiles)
|
||||||
|
{
|
||||||
|
// We expect 4 binaries: clearkey, libxul, plugin-container, and Firefox.
|
||||||
|
bool rv = (aNumFiles == 4);
|
||||||
|
// Verify that each binary is readable inside the sandbox,
|
||||||
|
// and close the handle.
|
||||||
|
for (uint32_t i = 0; i < aNumFiles; i++) {
|
||||||
|
const cdm::HostFile& hostFile = aHostFiles[i];
|
||||||
|
if (hostFile.file != cdm::kInvalidPlatformFile) {
|
||||||
|
if (!CanReadSome(hostFile.file)) {
|
||||||
|
rv = false;
|
||||||
|
}
|
||||||
|
ClosePlatformFile(hostFile.file);
|
||||||
|
}
|
||||||
|
if (hostFile.sig_file != cdm::kInvalidPlatformFile) {
|
||||||
|
ClosePlatformFile(hostFile.sig_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sCanReadHostVerificationFiles = rv;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C".
|
||||||
|
|
Загрузка…
Ссылка в новой задаче