Skip to content

Commit ab6010b

Browse files
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
1 parent 09a48a1 commit ab6010b

23 files changed

+264
-16
lines changed

chrome/browser/chromeos/preferences.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "chrome/browser/chromeos/input_method/input_method_util.h"
1616
#include "chrome/browser/chromeos/input_method/xkeyboard.h"
1717
#include "chrome/browser/chromeos/login/login_utils.h"
18+
#include "chrome/browser/chromeos/system/drm_settings.h"
1819
#include "chrome/browser/chromeos/system/input_device_settings.h"
1920
#include "chrome/browser/chromeos/system/screen_locker_settings.h"
2021
#include "chrome/browser/prefs/pref_member.h"
@@ -251,6 +252,12 @@ void Preferences::RegisterUserPrefs(PrefService* prefs) {
251252
prefs->RegisterStringPref(prefs::kOAuth1Secret,
252253
"",
253254
PrefService::UNSYNCABLE_PREF);
255+
256+
// TODO(wad): Once UI is connected, a final default can be set. At that point
257+
// change this pref from UNSYNCABLE to SYNCABLE.
258+
prefs->RegisterBooleanPref(prefs::kEnableCrosDRM,
259+
true,
260+
PrefService::UNSYNCABLE_PREF);
254261
}
255262

256263
// static
@@ -334,6 +341,8 @@ void Preferences::InitUserPrefs(PrefService* prefs) {
334341
prefs::kLanguageXkbAutoRepeatInterval, prefs, this);
335342

336343
enable_screen_lock_.Init(prefs::kEnableScreenLock, prefs, this);
344+
345+
enable_drm_.Init(prefs::kEnableCrosDRM, prefs, this);
337346
}
338347

339348
void Preferences::Init(PrefService* prefs) {
@@ -562,6 +571,11 @@ void Preferences::NotifyPrefChanged(const std::string* pref_name) {
562571
system::screen_locker_settings::EnableScreenLock(
563572
enable_screen_lock_.GetValue());
564573
}
574+
575+
// Init or update protected content (DRM) support.
576+
if (!pref_name || *pref_name == prefs::kEnableCrosDRM) {
577+
system::ToggleDrm(enable_drm_.GetValue());
578+
}
565579
}
566580

567581
void Preferences::SetLanguageConfigBoolean(const char* section,

chrome/browser/chromeos/preferences.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ class Preferences : public content::NotificationObserver {
157157

158158
BooleanPrefMember enable_screen_lock_;
159159

160+
BooleanPrefMember enable_drm_;
161+
160162
DISALLOW_COPY_AND_ASSIGN(Preferences);
161163
};
162164

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "chrome/browser/chromeos/system/drm_settings.h"
6+
7+
#include "base/bind.h"
8+
#include "base/chromeos/chromeos_version.h"
9+
#include "base/command_line.h"
10+
#include "base/file_path.h"
11+
#include "base/file_util.h"
12+
#include "base/path_service.h"
13+
#include "base/string_number_conversions.h"
14+
#include "base/string_util.h"
15+
#include "chrome/browser/chromeos/cros/cros_library.h"
16+
#include "chrome/browser/chromeos/cros/cryptohome_library.h"
17+
#include "chrome/browser/chromeos/login/user_manager.h"
18+
#include "chrome/common/chrome_paths.h"
19+
#include "chrome/common/chrome_switches.h"
20+
#include "content/public/browser/browser_thread.h"
21+
#include "crypto/encryptor.h"
22+
#include "crypto/sha2.h"
23+
24+
using content::BrowserThread;
25+
26+
namespace {
27+
28+
// This constant is mirrored in
29+
// content/browser/renderer_host/pepper_message_filter.cc
30+
// for OnGetDeviceID.
31+
//
32+
// This ID file is solely for use via the private pepper API.
33+
//
34+
// NOTE! Changing this value will also change the generated value
35+
// do not do so without accounting for the change.
36+
const char kDRMIdentifierFile[] = "Pepper DRM ID.0";
37+
38+
void ManageDrmIdentifierOnFileThread(bool enable, const std::string& email) {
39+
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
40+
41+
// Drop the file under <data>/<profile>/<drm id file>.
42+
// TODO(wad) get the profile directory in a more succinct fashion.
43+
FilePath drm_id_file;
44+
PathService::Get(chrome::DIR_USER_DATA, &drm_id_file);
45+
const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
46+
FilePath profile = cmd_line.GetSwitchValuePath(switches::kLoginProfile);
47+
if (profile.empty()) {
48+
LOG(ERROR) << "called with no login-profile!";
49+
return;
50+
}
51+
drm_id_file = drm_id_file.AppendASCII(profile.value());
52+
drm_id_file = drm_id_file.AppendASCII(kDRMIdentifierFile);
53+
54+
// The file will be regenerated or deleted at toggle-time.
55+
file_util::Delete(drm_id_file, false);
56+
57+
// If DRM support is disabled, then do nothing else.
58+
if (!enable)
59+
return;
60+
61+
// Build the identifier as follows:
62+
// SHA256(system-salt||service||SHA256(system-salt||service||email))
63+
chromeos::CryptohomeLibrary* c_home =
64+
chromeos::CrosLibrary::Get()->GetCryptohomeLibrary();
65+
std::string salt = c_home->GetSystemSalt();
66+
char id_buf[256 / 8]; // 256-bits for SHA256
67+
std::string input = salt;
68+
input.append(kDRMIdentifierFile);
69+
input.append(email);
70+
crypto::SHA256HashString(input, &id_buf, sizeof(id_buf));
71+
std::string id = StringToLowerASCII(base::HexEncode(
72+
reinterpret_cast<const void*>(id_buf),
73+
sizeof(id_buf)));
74+
input = salt;
75+
input.append(kDRMIdentifierFile);
76+
input.append(id);
77+
crypto::SHA256HashString(input, &id_buf, sizeof(id_buf));
78+
id = StringToLowerASCII(base::HexEncode(
79+
reinterpret_cast<const void*>(id_buf),
80+
sizeof(id_buf)));
81+
82+
if (file_util::WriteFile(drm_id_file, id.c_str(), id.length()) !=
83+
static_cast<int>(id.length())) {
84+
LOG(ERROR) << "Failed to write " << drm_id_file.value();
85+
return;
86+
}
87+
}
88+
89+
} // namespace
90+
91+
namespace chromeos {
92+
namespace system {
93+
94+
void ToggleDrm(bool enable) {
95+
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96+
97+
// Never generate the file in Guest mode.
98+
if (UserManager::Get()->IsLoggedInAsGuest() ||
99+
UserManager::Get()->IsLoggedInAsDemoUser())
100+
return;
101+
102+
// The user email address is included in the hash to keep the identifier
103+
// from being the same across users.
104+
std::string email = UserManager::Get()->GetLoggedInUser().email();
105+
DCHECK(email.length() == 0);
106+
107+
// Generate a DRM identifier on the FILE thread.
108+
// The DRM identifier is a per-user, per-OS-install identifier that is used
109+
// by privileged pepper plugins specifically for deriving
110+
// per-content-provider identifiers. The user must be able to clear it,
111+
// reset it, and deny its use.
112+
BrowserThread::PostTask(
113+
BrowserThread::FILE, FROM_HERE,
114+
base::Bind(&ManageDrmIdentifierOnFileThread, enable, email));
115+
}
116+
117+
} // namespace system
118+
} // namespace chromeos
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef CHROME_BROWSER_CHROMEOS_SYSTEM_DRM_SETTINGS_H_
6+
#define CHROME_BROWSER_CHROMEOS_SYSTEM_DRM_SETTINGS_H_
7+
#pragma once
8+
9+
namespace chromeos {
10+
namespace system {
11+
12+
// Enables/disables platform-specific DRM support.
13+
void ToggleDrm(bool enable);
14+
15+
} // namespace system
16+
} // namespace chromeos
17+
18+
#endif // CHROME_BROWSER_CHROMEOS_SYSTEM_DRM_SETTINGS_H_

chrome/chrome_browser.gypi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,8 @@
821821
'browser/chromeos/stub_cros_settings_provider.h',
822822
'browser/chromeos/system/ash_system_tray_delegate.cc',
823823
'browser/chromeos/system/ash_system_tray_delegate.h',
824+
'browser/chromeos/system/drm_settings.cc',
825+
'browser/chromeos/system/drm_settings.h',
824826
'browser/chromeos/system/input_device_settings.cc',
825827
'browser/chromeos/system/input_device_settings.h',
826828
'browser/chromeos/system/name_value_pairs_parser.cc',

chrome/common/pref_names.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,9 @@ const char kOAuth1Token[] = "settings.account.oauth1_token";
672672

673673
// A string prefs for OAuth1 secret.
674674
const char kOAuth1Secret[] = "settings.account.oauth1_secret";
675+
676+
// A boolean pref that enables the (private) pepper GetID() call.
677+
const char kEnableCrosDRM[] = "settings.privacy.drm_enabled";
675678
#endif // defined(OS_CHROMEOS)
676679

677680
// The disabled messages in IPC logging.

chrome/common/pref_names.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ extern const char kShow3gPromoNotification[];
244244
extern const char kUseSharedProxies[];
245245
extern const char kOAuth1Token[];
246246
extern const char kOAuth1Secret[];
247+
extern const char kEnableCrosDRM[];
247248
#endif // defined(OS_CHROMEOS)
248249
extern const char kIpcDisabledMessages[];
249250
extern const char kShowHomeButton[];

chrome/test/ui/ppapi_uitest.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,11 +866,13 @@ TEST_PPAPI_IN_PROCESS(Flash_GetProxyForURL)
866866
TEST_PPAPI_IN_PROCESS(Flash_MessageLoop)
867867
TEST_PPAPI_IN_PROCESS(Flash_GetLocalTimeZoneOffset)
868868
TEST_PPAPI_IN_PROCESS(Flash_GetCommandLineArgs)
869+
TEST_PPAPI_IN_PROCESS(Flash_GetDeviceID)
869870
TEST_PPAPI_OUT_OF_PROCESS(Flash_SetInstanceAlwaysOnTop)
870871
TEST_PPAPI_OUT_OF_PROCESS(Flash_GetProxyForURL)
871872
TEST_PPAPI_OUT_OF_PROCESS(Flash_MessageLoop)
872873
TEST_PPAPI_OUT_OF_PROCESS(Flash_GetLocalTimeZoneOffset)
873874
TEST_PPAPI_OUT_OF_PROCESS(Flash_GetCommandLineArgs)
875+
TEST_PPAPI_OUT_OF_PROCESS(Flash_GetDeviceID)
874876

875877
TEST_PPAPI_IN_PROCESS(WebSocket_IsWebSocket)
876878
TEST_PPAPI_IN_PROCESS(WebSocket_UninitializedPropertiesAccess)

content/browser/renderer_host/pepper_message_filter.cc

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include "base/bind_helpers.h"
99
#include "base/callback.h"
1010
#include "base/compiler_specific.h"
11+
#include "base/file_path.h"
12+
#include "base/file_util.h"
1113
#include "base/logging.h"
1214
#include "base/memory/ref_counted.h"
1315
#include "base/memory/scoped_ptr.h"
@@ -23,6 +25,7 @@
2325
#include "content/browser/renderer_host/render_process_host_impl.h"
2426
#include "content/browser/renderer_host/render_view_host_impl.h"
2527
#include "content/common/pepper_messages.h"
28+
#include "content/public/browser/browser_context.h"
2629
#include "content/public/browser/browser_thread.h"
2730
#include "content/public/browser/content_browser_client.h"
2831
#include "content/public/browser/font_list_async.h"
@@ -55,18 +58,28 @@ namespace {
5558
const size_t kMaxSocketsAllowed = 1024;
5659
const uint32 kInvalidSocketID = 0;
5760

61+
// The ID is a 256-bit hash digest hex-encoded.
62+
const int kDRMIdentifierSize = (256 / 8) * 2;
63+
// The path to the file containing the DRM ID.
64+
// It is mirrored from
65+
// chrome/browser/chromeos/system/drm_settings.cc
66+
const char kDRMIdentifierFile[] = "Pepper DRM ID.0";
67+
5868
} // namespace
5969

6070
PepperMessageFilter::PepperMessageFilter(
6171
ProcessType type,
6272
int process_id,
63-
content::ResourceContext* resource_context)
73+
content::BrowserContext* browser_context)
6474
: process_type_(type),
6575
process_id_(process_id),
66-
resource_context_(resource_context),
76+
resource_context_(browser_context ?
77+
browser_context->GetResourceContext() : NULL),
6778
host_resolver_(NULL),
6879
next_socket_id_(1) {
6980
DCHECK(type == RENDERER);
81+
DCHECK(browser_context);
82+
browser_path_ = browser_context->GetPath();
7083
DCHECK(resource_context_);
7184
}
7285

@@ -90,7 +103,7 @@ void PepperMessageFilter::OverrideThreadForMessage(
90103
message.type() == PpapiHostMsg_PPBTCPServerSocket_Listen::ID ||
91104
message.type() == PpapiHostMsg_PPBHostResolver_Resolve::ID) {
92105
*thread = BrowserThread::UI;
93-
} else if (message.type() == PpapiHostMsg_PPBFlash_GetDeviceID::ID) {
106+
} else if (message.type() == PepperMsg_GetDeviceID::ID) {
94107
*thread = BrowserThread::FILE;
95108
}
96109
}
@@ -145,7 +158,7 @@ bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg,
145158

146159
// Flash messages.
147160
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_UpdateActivity, OnUpdateActivity)
148-
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFlash_GetDeviceID, OnGetDeviceID)
161+
IPC_MESSAGE_HANDLER(PepperMsg_GetDeviceID, OnGetDeviceID)
149162

150163
IPC_MESSAGE_UNHANDLED(handled = false)
151164
IPC_END_MESSAGE_MAP_EX()
@@ -633,8 +646,33 @@ void PepperMessageFilter::OnUpdateActivity() {
633646
}
634647

635648
void PepperMessageFilter::OnGetDeviceID(std::string* id) {
636-
// TODO(brettw) implement this.
637-
*id = "<undefined>";
649+
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
650+
id->clear();
651+
652+
// Grab the contents of the DRM identifier file.
653+
FilePath drm_id_file = browser_path_;
654+
drm_id_file = drm_id_file.AppendASCII(kDRMIdentifierFile);
655+
656+
// This method should not be called with high frequency and its
657+
// useful to be able to validate use with a VLOG.
658+
VLOG(1) << "DRM ID requested @ " << drm_id_file.value();
659+
660+
if (browser_path_.empty()) {
661+
LOG(ERROR) << "GetDeviceID requested from outside the RENDERER context.";
662+
return;
663+
}
664+
665+
// TODO(wad,brettw) Add OffTheRecord() enforcement here.
666+
// Normally this is left for the plugin to do, but in the
667+
// future we should check here as an added safeguard.
668+
669+
char id_buf[kDRMIdentifierSize];
670+
if (file_util::ReadFile(drm_id_file, id_buf, kDRMIdentifierSize) !=
671+
kDRMIdentifierSize) {
672+
VLOG(1) << "file not readable: " << drm_id_file.value();
673+
return;
674+
}
675+
id->assign(id_buf, kDRMIdentifierSize);
638676
}
639677

640678
void PepperMessageFilter::GetFontFamiliesComplete(

content/browser/renderer_host/pepper_message_filter.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <vector>
1212

1313
#include "base/basictypes.h"
14+
#include "base/file_path.h"
1415
#include "base/memory/linked_ptr.h"
1516
#include "base/memory/scoped_ptr.h"
1617
#include "base/process.h"
@@ -34,6 +35,7 @@ class ListValue;
3435
}
3536

3637
namespace content {
38+
class BrowserContext;
3739
class ResourceContext;
3840
}
3941

@@ -63,7 +65,7 @@ class PepperMessageFilter
6365
// provided for sanity checking).
6466
PepperMessageFilter(ProcessType type,
6567
int process_id,
66-
content::ResourceContext* resource_context);
68+
content::BrowserContext* browser_context);
6769

6870
// Constructor when used in the context of a PPAPI process (the argument is
6971
// provided for sanity checking).
@@ -252,6 +254,8 @@ class PepperMessageFilter
252254

253255
NetworkMonitorIdSet network_monitor_ids_;
254256

257+
FilePath browser_path_;
258+
255259
DISALLOW_COPY_AND_ASSIGN(PepperMessageFilter);
256260
};
257261

0 commit comments

Comments
 (0)