Title: [240804] trunk/Source/WebCore
Revision
240804
Author
jer.no...@apple.com
Date
2019-01-31 11:52:14 -0800 (Thu, 31 Jan 2019)

Log Message

[Cocoa][EME] Modern EME uses a different path for SecureStop data than Legacy EME
https://bugs.webkit.org/show_bug.cgi?id=193988

Reviewed by Jon Lee.

Modern EME is writing SecureStop data as a file at the same path as the
directory used by Legacy EME; meaning, when Modern EME attempts to write
to that file, it will fail because a directory exists at the same path.

Add a migration step to take care of those instances where Modern EME Secure
Stop data was already written to disk, and move that previously written data
to the correct file path.

* platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h:
* platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm:
(WebCore::CDMInstanceFairPlayStreamingAVFObjC::initializeWithConfiguration):
(WebCore::CDMInstanceFairPlayStreamingAVFObjC::setStorageDirectory):
(WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::updateLicense):
(WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::loadSession):
(WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::removeSessionData):
(WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::ensureSession):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (240803 => 240804)


--- trunk/Source/WebCore/ChangeLog	2019-01-31 19:49:43 UTC (rev 240803)
+++ trunk/Source/WebCore/ChangeLog	2019-01-31 19:52:14 UTC (rev 240804)
@@ -1,3 +1,27 @@
+2019-01-31  Jer Noble  <jer.no...@apple.com>
+
+        [Cocoa][EME] Modern EME uses a different path for SecureStop data than Legacy EME
+        https://bugs.webkit.org/show_bug.cgi?id=193988
+
+        Reviewed by Jon Lee.
+
+        Modern EME is writing SecureStop data as a file at the same path as the
+        directory used by Legacy EME; meaning, when Modern EME attempts to write
+        to that file, it will fail because a directory exists at the same path.
+
+        Add a migration step to take care of those instances where Modern EME Secure
+        Stop data was already written to disk, and move that previously written data
+        to the correct file path.
+
+        * platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h:
+        * platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm:
+        (WebCore::CDMInstanceFairPlayStreamingAVFObjC::initializeWithConfiguration):
+        (WebCore::CDMInstanceFairPlayStreamingAVFObjC::setStorageDirectory):
+        (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::updateLicense):
+        (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::loadSession):
+        (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::removeSessionData):
+        (WebCore::CDMInstanceSessionFairPlayStreamingAVFObjC::ensureSession):
+
 2019-01-31  Antti Koivisto  <an...@apple.com>
 
         Call the frame main contents layer "rootContentsLayer" consistently.

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h (240803 => 240804)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h	2019-01-31 19:49:43 UTC (rev 240803)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h	2019-01-31 19:52:14 UTC (rev 240804)
@@ -66,7 +66,7 @@
 
     const String& keySystem() const final;
 
-    NSURL *storageDirectory() const { return m_storageDirectory.get(); }
+    NSURL *storageURL() const { return m_storageURL.get(); }
     bool persistentStateAllowed() const { return m_persistentStateAllowed; }
     SharedBuffer* serverCertificate() const { return m_serverCertificate.get(); }
 
@@ -76,7 +76,7 @@
 private:
     RefPtr<SharedBuffer> m_serverCertificate;
     bool m_persistentStateAllowed { true };
-    RetainPtr<NSURL> m_storageDirectory;
+    RetainPtr<NSURL> m_storageURL;
     Vector<WeakPtr<CDMInstanceSessionFairPlayStreamingAVFObjC>> m_sessions;
 };
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm (240803 => 240804)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm	2019-01-31 19:49:43 UTC (rev 240803)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm	2019-01-31 19:52:14 UTC (rev 240804)
@@ -38,6 +38,7 @@
 #import <objc/runtime.h>
 #import <pal/spi/mac/AVFoundationSPI.h>
 #import <wtf/Algorithms.h>
+#import <wtf/FileSystem.h>
 #import <wtf/SoftLinking.h>
 #import <wtf/text/StringHash.h>
 
@@ -170,7 +171,7 @@
     if (configuration.persistentState != CDMRequirement::Required && (configuration.sessionTypes.contains(CDMSessionType::PersistentUsageRecord) || configuration.sessionTypes.contains(CDMSessionType::PersistentLicense)))
         return Failed;
 
-    if (configuration.persistentState == CDMRequirement::Required && !m_storageDirectory)
+    if (configuration.persistentState == CDMRequirement::Required && !m_storageURL)
         return Failed;
 
     if (configuration.sessionTypes.contains(CDMSessionType::PersistentLicense) && !supportsPersistentKeys())
@@ -202,10 +203,30 @@
 
 CDMInstance::SuccessValue CDMInstanceFairPlayStreamingAVFObjC::setStorageDirectory(const String& storageDirectory)
 {
-    if (storageDirectory.isEmpty())
-        m_storageDirectory = nil;
-    else
-        m_storageDirectory = adoptNS([[NSURL alloc] initFileURLWithPath:storageDirectory isDirectory:YES]);
+    if (storageDirectory.isEmpty()) {
+        m_storageURL = nil;
+        return Succeeded;
+    }
+
+    auto storagePath = FileSystem::pathByAppendingComponent(storageDirectory, "SecureStop.plist");
+
+    if (!FileSystem::fileExists(storageDirectory)) {
+        if (!FileSystem::makeAllDirectories(storageDirectory))
+            return Failed;
+    } else if (!FileSystem::fileIsDirectory(storageDirectory, FileSystem::ShouldFollowSymbolicLinks::Yes)) {
+        auto tempDirectory = FileSystem::createTemporaryDirectory(@"MediaKeys");
+        if (!tempDirectory)
+            return Failed;
+
+        auto tempStoragePath = FileSystem::pathByAppendingComponent(tempDirectory, FileSystem::pathGetFileName(storagePath));
+        if (!FileSystem::moveFile(storageDirectory, tempStoragePath))
+            return Failed;
+
+        if (!FileSystem::moveFile(tempDirectory, storageDirectory))
+            return Failed;
+    }
+
+    m_storageURL = adoptNS([[NSURL alloc] initFileURLWithPath:storagePath isDirectory:NO]);
     return Succeeded;
 }
 
@@ -341,15 +362,15 @@
             [expiredSessions addObject:session.get()];
 
         auto* certificate = m_instance->serverCertificate();
-        auto* storageDirectory = m_instance->storageDirectory();
+        auto* storageURL = m_instance->storageURL();
 
-        if (!certificate || !storageDirectory) {
+        if (!certificate || !storageURL) {
             callback(false, WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed);
             return;
         }
 
         RetainPtr<NSData> appIdentifier = certificate->createNSData();
-        [getAVContentKeySessionClass() removePendingExpiredSessionReports:expiredSessions.get() withAppIdentifier:appIdentifier.get() storageDirectoryAtURL:storageDirectory];
+        [getAVContentKeySessionClass() removePendingExpiredSessionReports:expiredSessions.get() withAppIdentifier:appIdentifier.get() storageDirectoryAtURL:storageURL];
         callback(false, { }, WTF::nullopt, WTF::nullopt, Succeeded);
         return;
     }
@@ -389,8 +410,8 @@
 {
     UNUSED_PARAM(origin);
     if (licenseType == LicenseType::PersistentUsageRecord) {
-        auto* storageDirectory = m_instance->storageDirectory();
-        if (!m_instance->persistentStateAllowed() || storageDirectory) {
+        auto* storageURL = m_instance->storageURL();
+        if (!m_instance->persistentStateAllowed() || storageURL) {
             callback(WTF::nullopt, WTF::nullopt, WTF::nullopt, Failed, SessionLoadFailure::MismatchedSessionType);
             return;
         }
@@ -402,7 +423,7 @@
 
         RetainPtr<NSData> appIdentifier = certificate->createNSData();
         KeyStatusVector changedKeys;
-        for (NSData* expiredSessionData in [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:appIdentifier.get() storageDirectoryAtURL:storageDirectory]) {
+        for (NSData* expiredSessionData in [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:appIdentifier.get() storageDirectoryAtURL:storageURL]) {
             NSDictionary *expiredSession = [NSPropertyListSerialization propertyListWithData:expiredSessionData options:kCFPropertyListImmutable format:nullptr error:nullptr];
             NSString *playbackSessionIdValue = (NSString *)[expiredSession objectForKey:PlaybackSessionIdKey];
             if (![playbackSessionIdValue isKindOfClass:[NSString class]])
@@ -450,10 +471,10 @@
     [m_session expire];
 
     if (licenseType == LicenseType::PersistentUsageRecord) {
-        auto* storageDirectory = m_instance->storageDirectory();
+        auto* storageURL = m_instance->storageURL();
         auto* certificate = m_instance->serverCertificate();
 
-        if (!m_instance->persistentStateAllowed() || !storageDirectory || !certificate) {
+        if (!m_instance->persistentStateAllowed() || !storageURL || !certificate) {
             callback({ }, WTF::nullopt, Failed);
             return;
         }
@@ -461,7 +482,7 @@
         RetainPtr<NSData> appIdentifier = certificate->createNSData();
         RetainPtr<NSMutableArray> expiredSessionsArray = adoptNS([[NSMutableArray alloc] init]);
         KeyStatusVector changedKeys;
-        for (NSData* expiredSessionData in [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:appIdentifier.get() storageDirectoryAtURL:storageDirectory]) {
+        for (NSData* expiredSessionData in [getAVContentKeySessionClass() pendingExpiredSessionReportsWithAppIdentifier:appIdentifier.get() storageDirectoryAtURL:storageURL]) {
             NSDictionary *expiredSession = [NSPropertyListSerialization propertyListWithData:expiredSessionData options:kCFPropertyListImmutable format:nullptr error:nullptr];
             NSString *playbackSessionIdValue = (NSString *)[expiredSession objectForKey:PlaybackSessionIdKey];
             if (![playbackSessionIdValue isKindOfClass:[NSString class]])
@@ -692,11 +713,11 @@
     if (m_session)
         return m_session.get();
 
-    auto* storageDirectory = m_instance->storageDirectory();
-    if (!m_instance->persistentStateAllowed() || !storageDirectory)
+    auto storageURL = m_instance->storageURL();
+    if (!m_instance->persistentStateAllowed() || !storageURL)
         m_session = [getAVContentKeySessionClass() contentKeySessionWithKeySystem:getAVContentKeySystemFairPlayStreaming()];
     else
-        m_session = [getAVContentKeySessionClass() contentKeySessionWithKeySystem:getAVContentKeySystemFairPlayStreaming() storageDirectoryAtURL:storageDirectory];
+        m_session = [getAVContentKeySessionClass() contentKeySessionWithKeySystem:getAVContentKeySystemFairPlayStreaming() storageDirectoryAtURL:storageURL];
 
     if (!m_session)
         return nullptr;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to