Generate and connect a Pepper identifier for Chrome OS
This change wires up GetDeviceID and passes in the BrowserContext into
PepperMessageFilter rather than the extracted ResourceContext.
The pepper drm identifier is a value provided for use by flash. It may
be reset or disabled by the user and cannot function in OffTheRecord
embodiments.
In Guest mode, the identifier is never generated. When in incognito,
the ppapi plugin will be informed of the the profile state and not make
the call. Later, this will be enforced in the message filter as well.
Note, the preference is currently defaulted to true and does not have a
UI connection. The UI is being wired up as part of crbug.com/125899.
At which point, we can make the setting syncable and chose the preferred
default.
This change bounces the GetDeviceID call through the renderer back to
the browser so that we have the path context to read the file from.
This same approach can be used to allow OTR checking and preference
reading if that is preferable to a file. If we need to do anything on
the UI thread, we should do everything there (OTR+Pref).
Since the ID is regenerated at every pref init/toggle, we can move the
value around without impacting users in the future.
Please let me know if I've totally botched the wiring for this. I'm not
sure the best way to fully test it.
TEST=built and tested on x86-alex target:
- ID is generated for normal sign-in in /home/chronos/user and is not generated for Guest.
- Very lightweight ppapi test was run too.
(Still need pointers on better flash api wiring testing to make sure it is seeing right string)
- Pepper flash still worked normally
Also built full x86-alex system image:
- booted it
- checked the file existence in both modes
- checked pepflash and talk video for normal functionality
TRYBOT=http://build.chromium.org/p/tryserver.chromium/builders/cros_x86/builds/353
BUG=chromium-os:30378
Change-Id: Ibfbc484918d94147ad4fdc522a6415c71731068b
R=brettw,sky,piman,viettrungluu
Review URL: http://codereview.chromium.org/10342013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135255 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index f84b155e..1c0c69a 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/chromeos/input_method/xkeyboard.h"
#include "chrome/browser/chromeos/login/login_utils.h"
+#include "chrome/browser/chromeos/system/drm_settings.h"
#include "chrome/browser/chromeos/system/input_device_settings.h"
#include "chrome/browser/chromeos/system/screen_locker_settings.h"
#include "chrome/browser/prefs/pref_member.h"
@@ -251,6 +252,12 @@
prefs->RegisterStringPref(prefs::kOAuth1Secret,
"",
PrefService::UNSYNCABLE_PREF);
+
+ // TODO(wad): Once UI is connected, a final default can be set. At that point
+ // change this pref from UNSYNCABLE to SYNCABLE.
+ prefs->RegisterBooleanPref(prefs::kEnableCrosDRM,
+ true,
+ PrefService::UNSYNCABLE_PREF);
}
// static
@@ -334,6 +341,8 @@
prefs::kLanguageXkbAutoRepeatInterval, prefs, this);
enable_screen_lock_.Init(prefs::kEnableScreenLock, prefs, this);
+
+ enable_drm_.Init(prefs::kEnableCrosDRM, prefs, this);
}
void Preferences::Init(PrefService* prefs) {
@@ -562,6 +571,11 @@
system::screen_locker_settings::EnableScreenLock(
enable_screen_lock_.GetValue());
}
+
+ // Init or update protected content (DRM) support.
+ if (!pref_name || *pref_name == prefs::kEnableCrosDRM) {
+ system::ToggleDrm(enable_drm_.GetValue());
+ }
}
void Preferences::SetLanguageConfigBoolean(const char* section,
diff --git a/chrome/browser/chromeos/preferences.h b/chrome/browser/chromeos/preferences.h
index d8b5528a..d624b28 100644
--- a/chrome/browser/chromeos/preferences.h
+++ b/chrome/browser/chromeos/preferences.h
@@ -157,6 +157,8 @@
BooleanPrefMember enable_screen_lock_;
+ BooleanPrefMember enable_drm_;
+
DISALLOW_COPY_AND_ASSIGN(Preferences);
};
diff --git a/chrome/browser/chromeos/system/drm_settings.cc b/chrome/browser/chromeos/system/drm_settings.cc
new file mode 100644
index 0000000..2db1365d
--- /dev/null
+++ b/chrome/browser/chromeos/system/drm_settings.cc
@@ -0,0 +1,118 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/system/drm_settings.h"
+
+#include "base/bind.h"
+#include "base/chromeos/chromeos_version.h"
+#include "base/command_line.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/string_number_conversions.h"
+#include "base/string_util.h"
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/cros/cryptohome_library.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "content/public/browser/browser_thread.h"
+#include "crypto/encryptor.h"
+#include "crypto/sha2.h"
+
+using content::BrowserThread;
+
+namespace {
+
+// This constant is mirrored in
+// content/browser/renderer_host/pepper_message_filter.cc
+// for OnGetDeviceID.
+//
+// This ID file is solely for use via the private pepper API.
+//
+// NOTE! Changing this value will also change the generated value
+// do not do so without accounting for the change.
+const char kDRMIdentifierFile[] = "Pepper DRM ID.0";
+
+void ManageDrmIdentifierOnFileThread(bool enable, const std::string& email) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ // Drop the file under <data>/<profile>/<drm id file>.
+ // TODO(wad) get the profile directory in a more succinct fashion.
+ FilePath drm_id_file;
+ PathService::Get(chrome::DIR_USER_DATA, &drm_id_file);
+ const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
+ FilePath profile = cmd_line.GetSwitchValuePath(switches::kLoginProfile);
+ if (profile.empty()) {
+ LOG(ERROR) << "called with no login-profile!";
+ return;
+ }
+ drm_id_file = drm_id_file.AppendASCII(profile.value());
+ drm_id_file = drm_id_file.AppendASCII(kDRMIdentifierFile);
+
+ // The file will be regenerated or deleted at toggle-time.
+ file_util::Delete(drm_id_file, false);
+
+ // If DRM support is disabled, then do nothing else.
+ if (!enable)
+ return;
+
+ // Build the identifier as follows:
+ // SHA256(system-salt||service||SHA256(system-salt||service||email))
+ chromeos::CryptohomeLibrary* c_home =
+ chromeos::CrosLibrary::Get()->GetCryptohomeLibrary();
+ std::string salt = c_home->GetSystemSalt();
+ char id_buf[256 / 8]; // 256-bits for SHA256
+ std::string input = salt;
+ input.append(kDRMIdentifierFile);
+ input.append(email);
+ crypto::SHA256HashString(input, &id_buf, sizeof(id_buf));
+ std::string id = StringToLowerASCII(base::HexEncode(
+ reinterpret_cast<const void*>(id_buf),
+ sizeof(id_buf)));
+ input = salt;
+ input.append(kDRMIdentifierFile);
+ input.append(id);
+ crypto::SHA256HashString(input, &id_buf, sizeof(id_buf));
+ id = StringToLowerASCII(base::HexEncode(
+ reinterpret_cast<const void*>(id_buf),
+ sizeof(id_buf)));
+
+ if (file_util::WriteFile(drm_id_file, id.c_str(), id.length()) !=
+ static_cast<int>(id.length())) {
+ LOG(ERROR) << "Failed to write " << drm_id_file.value();
+ return;
+ }
+}
+
+} // namespace
+
+namespace chromeos {
+namespace system {
+
+void ToggleDrm(bool enable) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ // Never generate the file in Guest mode.
+ if (UserManager::Get()->IsLoggedInAsGuest() ||
+ UserManager::Get()->IsLoggedInAsDemoUser())
+ return;
+
+ // The user email address is included in the hash to keep the identifier
+ // from being the same across users.
+ std::string email = UserManager::Get()->GetLoggedInUser().email();
+ DCHECK(email.length() == 0);
+
+ // Generate a DRM identifier on the FILE thread.
+ // The DRM identifier is a per-user, per-OS-install identifier that is used
+ // by privileged pepper plugins specifically for deriving
+ // per-content-provider identifiers. The user must be able to clear it,
+ // reset it, and deny its use.
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&ManageDrmIdentifierOnFileThread, enable, email));
+}
+
+} // namespace system
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/system/drm_settings.h b/chrome/browser/chromeos/system/drm_settings.h
new file mode 100644
index 0000000..bcb7487
--- /dev/null
+++ b/chrome/browser/chromeos/system/drm_settings.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_SYSTEM_DRM_SETTINGS_H_
+#define CHROME_BROWSER_CHROMEOS_SYSTEM_DRM_SETTINGS_H_
+#pragma once
+
+namespace chromeos {
+namespace system {
+
+// Enables/disables platform-specific DRM support.
+void ToggleDrm(bool enable);
+
+} // namespace system
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_SYSTEM_DRM_SETTINGS_H_