Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable widevine on linux #3037

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const Config = function () {
this.braveReferralsApiKey = getNPMConfig(['brave_referrals_api_key']) || ''
this.ignore_compile_failure = false
this.enable_hangout_services_extension = true

this.widevineVersion = getNPMConfig(['widevine', 'version'])
}

Config.prototype.buildArgs = function () {
Expand All @@ -73,7 +73,7 @@ Config.prototype.buildArgs = function () {
ffmpeg_branding: "Chrome",
enable_nacl: false,
// branding_path_component: "brave",
enable_widevine: process.platform !== 'linux',
enable_widevine: true,
target_cpu: this.targetArch,
is_official_build: this.officialBuild,
is_debug: this.buildConfig !== 'Release',
Expand Down
73 changes: 73 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const config = require('./config')
const fs = require('fs-extra')
const crypto = require('crypto')
const autoGeneratedBraveToChromiumMapping = Object.assign({}, require('./l10nUtil').autoGeneratedBraveToChromiumMapping)
const admZip = require('adm-zip')
const request = require('sync-request')

const runGClient = (args, options = {}) => {
if (config.gClientVerbose) args.push('--verbose')
Expand Down Expand Up @@ -208,6 +210,76 @@ const util = {
fs.copySync(srcDir, dstDir)
},

// In linux, WidevineCdm library is bundled instead of installing it by component
// updating during the runtime. In linux, we can't load cdm library during the runtime
// because processes except browser process are forked from zygote process not created from
// brave.exe binary. So, cdm should be loaded(not initialized) into zygote process space
// before zygote enters the sandbox.
// This method places WidevineCdm lib and header file into proper place before building.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for delay in reviewing this, but for licensing reasons it's not allowed for us to bundle.
This will need to happen on each client and we should use an npm config variable likebrave_google_api_endpoint

prepareWidevineCdmLibIfNeeded: () => {
const widevineDir = path.join(config.srcDir, 'third_party', 'widevine', 'cdm', 'linux', 'x64')
fs.ensureDirSync(widevineDir)

const widevineConfig = {
widevineDir,
configuredVersion: config.widevineVersion,
versionFilePath: path.join(widevineDir, 'version'),
widevineCdmHeaderFilePath: path.join(widevineDir, 'widevine_cdm_version.h'),
widevineCdmLibFilePath: path.join(widevineDir, 'libwidevinecdm.so')
}

// If version file isn't existed, do fresh install.
if (!fs.existsSync(widevineConfig.versionFilePath)) {
console.log("No widevine version file.")
util.doPrepareWidevineCdmLib(widevineConfig)
return
}

// If installed version is different with configured version, do fresh install.
const installedVersion = fs.readFileSync(widevineConfig.versionFilePath, 'utf8')
if (installedVersion !== widevineConfig.configuredVersion) {
console.log("Different widevine version is installed")
util.doPrepareWidevineCdmLib(widevineConfig)
return
}

// Double check necessary header and lib exists.
if (fs.existsSync(widevineConfig.widevineCdmHeaderFilePath) &&
fs.existsSync(widevineConfig.widevineCdmLibFilePath))
return;

util.doPrepareWidevineCdmLib(widevineConfig)
},

doPrepareWidevineCdmLib: (widevineConfig) => {
console.log('Install widevinecdm library')

// Create version file.
fs.writeFileSync(widevineConfig.versionFilePath, widevineConfig.configuredVersion)

// Crate header file.
const headerFileContent =
`#ifndef WIDEVINE_CDM_VERSION_H_
#define WIDEVINE_CDM_VERSION_H_
#define WIDEVINE_CDM_VERSION_STRING \"${widevineConfig.configuredVersion}\"
#endif // WIDEVINE_CDM_VERSION_H_`;
fs.writeFileSync(widevineConfig.widevineCdmHeaderFilePath, headerFileContent)

// Synchronously download widevine pkg and extracts into cdm dir.
const widevineZipFileName = `${widevineConfig.configuredVersion}-linux-x64.zip`
const widevineUrl = `https://redirector.gvt1.com/edgedl/widevine-cdm/${widevineZipFileName}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if downloading a new binary each time (instead of the manual binary update) is OK from the security point of view, so maybe it is worth to show this to someone from DevOps or security teams.

Copy link
Member Author

@simonhong simonhong Jan 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bbondy I think we also need to think about widevine download url could be exposed or not. Also, as far as we use bundling, I think manual binary update seems fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please post a security review for this PR entirely in brave/internal

const res = request('GET', widevineUrl)
const widevineZipFilePath = path.join(widevineConfig.widevineDir, widevineZipFileName)
fs.writeFileSync(widevineZipFilePath, res.body)
const zip = new admZip(widevineZipFilePath);
zip.extractAllTo(widevineConfig.widevineDir, true)
// During the create_dist, /usr/lib/rpm/elfdeps requires that binaries have an exectuable bit set.
fs.chmodSync(widevineConfig.widevineCdmLibFilePath, 0o755)

// Delete zip file.
fs.removeSync(widevineZipFilePath)
},

signApp: (options = config.defaultOptions) => {
console.log('signing ...')

Expand All @@ -218,6 +290,7 @@ const util = {
console.log('building ' + config.buildTarget + '...')

if (process.platform === 'win32') util.updateOmahaMidlFiles()
if (process.platform === 'linux') util.prepareWidevineCdmLibIfNeeded()

let num_compile_failure = 1
if (config.ignore_compile_failure)
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
"url": "https://github.com/brave/brave-core.git"
}
}
},
"widevine": {
"version": "4.10.1196.0"
}
},
"repository": {
Expand Down Expand Up @@ -252,8 +255,10 @@
},
"homepage": "https://github.com/brave/brave-browser#readme",
"dependencies": {
"adm-zip": "^0.4.13",
"commander": "^2.9.0",
"fs-extra": "^1.0.0"
"fs-extra": "^1.0.0",
"sync-request": "^6.0.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If i'm not mistaken, these can be devDependencies instead of dependencies. (npm install --save-dev)

},
"devDependencies": {
"ip": "^1.1.5"
Expand Down