⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286075 in webkit


Ignore:
Timestamp:
Nov 19, 2021, 1:43:17 PM (5 years ago)
Author:
beidson@apple.com
Message:

More webpushd architecture work
https://bugs.webkit.org/show_bug.cgi?id=233295

Reviewed by Alex Christensen.

Source/WebKit:

Covered by API tests.

This patch:

  • Adds entitlement checks for connections to webpushd
  • Adds a "ClientConnection" object to the daemon to manage per-connection state
  • Adds a debug enabled setting
  • Adds the ability for the connecting app (com.apple.WebKit.Networking) to pass the host app's audit_token
  • Tests some of the above
  • Adds the beginnings of other future infrastructure
  • NetworkProcess/Notifications/NetworkNotificationManager.cpp:

(WebKit::NetworkNotificationManager::NetworkNotificationManager):

  • Resources/ios/XPCService-embedded-simulator.entitlements:
  • Scripts/process-entitlements.sh:
  • Shared/Cocoa/CodeSigning.h:
  • Shared/Cocoa/CodeSigning.mm:

(WebKit::codeSigningIdentifierAndPlatformBinaryStatus):
(WebKit::codeSigningIdentifier):

  • Shared/WebPushDaemonConstants.h:

(WebKit::WebPushD::messageTypeSendsReply):

  • WebKit.xcodeproj/project.pbxproj:
  • webpushd/PushClientConnection.h: Copied from Source/WebKit/Shared/Cocoa/CodeSigning.h.

(WebPushD::ClientConnection::hasAuditToken const):
(WebPushD::ClientConnection::debugModeIsEnabled const):

  • webpushd/PushClientConnection.mm: Added.

(WebPushD::ClientConnection::ClientConnection):
(WebPushD::ClientConnection::setAuditTokenData):
(WebPushD::ClientConnection::hostCodeSigningIdentifier):
(WebPushD::ClientConnection::hostHasPushEntitlement):
(WebPushD::ClientConnection::setDebugModeIsEnabled):

  • webpushd/WebPushDaemon.h:
  • webpushd/WebPushDaemon.mm:

(WebPushD::handleWebPushDMessageWithReply):
(WebPushD::handleWebPushDMessage):
(WebPushD::Daemon::broadcastDebugMessage):
(WebPushD::Daemon::connectionEventHandler):
(WebPushD::Daemon::connectionAdded):
(WebPushD::Daemon::connectionRemoved):
(WebPushD::Daemon::decodeAndHandleMessage):
(WebPushD::Daemon::echoTwice):
(WebPushD::Daemon::canRegisterForNotifications):
(WebPushD::Daemon::requestSystemNotificationPermission):
(WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
(WebPushD::Daemon::deletePushAndNotificationRegistration):
(WebPushD::Daemon::setHostAppAuditToken):
(WebPushD::Daemon::setDebugModeIsEnabled):
(WebPushD::Daemon::toClientConnection):

  • webpushd/WebPushDaemonMain.mm:

(main):

Tools:

  • TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements:
  • TestWebKitAPI/Configurations/TestWebKitAPI-macOS-internal.entitlements:
  • TestWebKitAPI/Configurations/TestWebKitAPI-macOS.entitlements:
  • TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:

(TestWebKitAPI::TEST):

Location:
trunk
Files:
1 added
17 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r286073 r286075  
     12021-11-19  Brady Eidson  <beidson@apple.com>
     2
     3        More webpushd architecture work
     4        https://bugs.webkit.org/show_bug.cgi?id=233295
     5
     6        Reviewed by Alex Christensen.
     7
     8        Covered by API tests.
     9       
     10        This patch:
     11        - Adds entitlement checks for connections to webpushd
     12        - Adds a "ClientConnection" object to the daemon to manage per-connection state
     13        - Adds a debug enabled setting
     14        - Adds the ability for the connecting app (com.apple.WebKit.Networking) to pass the host app's audit_token
     15        - Tests some of the above
     16        - Adds the beginnings of other future infrastructure
     17
     18        * NetworkProcess/Notifications/NetworkNotificationManager.cpp:
     19        (WebKit::NetworkNotificationManager::NetworkNotificationManager):
     20
     21        * Resources/ios/XPCService-embedded-simulator.entitlements:
     22        * Scripts/process-entitlements.sh:
     23
     24        * Shared/Cocoa/CodeSigning.h:
     25        * Shared/Cocoa/CodeSigning.mm:
     26        (WebKit::codeSigningIdentifierAndPlatformBinaryStatus):
     27        (WebKit::codeSigningIdentifier):
     28
     29        * Shared/WebPushDaemonConstants.h:
     30        (WebKit::WebPushD::messageTypeSendsReply):
     31
     32        * WebKit.xcodeproj/project.pbxproj:
     33
     34        * webpushd/PushClientConnection.h: Copied from Source/WebKit/Shared/Cocoa/CodeSigning.h.
     35        (WebPushD::ClientConnection::hasAuditToken const):
     36        (WebPushD::ClientConnection::debugModeIsEnabled const):
     37        * webpushd/PushClientConnection.mm: Added.
     38        (WebPushD::ClientConnection::ClientConnection):
     39        (WebPushD::ClientConnection::setAuditTokenData):
     40        (WebPushD::ClientConnection::hostCodeSigningIdentifier):
     41        (WebPushD::ClientConnection::hostHasPushEntitlement):
     42        (WebPushD::ClientConnection::setDebugModeIsEnabled):
     43
     44        * webpushd/WebPushDaemon.h:
     45        * webpushd/WebPushDaemon.mm:
     46        (WebPushD::handleWebPushDMessageWithReply):
     47        (WebPushD::handleWebPushDMessage):
     48        (WebPushD::Daemon::broadcastDebugMessage):
     49        (WebPushD::Daemon::connectionEventHandler):
     50        (WebPushD::Daemon::connectionAdded):
     51        (WebPushD::Daemon::connectionRemoved):
     52        (WebPushD::Daemon::decodeAndHandleMessage):
     53        (WebPushD::Daemon::echoTwice):
     54        (WebPushD::Daemon::canRegisterForNotifications):
     55        (WebPushD::Daemon::requestSystemNotificationPermission):
     56        (WebPushD::Daemon::getOriginsWithPushAndNotificationPermissions):
     57        (WebPushD::Daemon::deletePushAndNotificationRegistration):
     58        (WebPushD::Daemon::setHostAppAuditToken):
     59        (WebPushD::Daemon::setDebugModeIsEnabled):
     60        (WebPushD::Daemon::toClientConnection):
     61        * webpushd/WebPushDaemonMain.mm:
     62        (main):
     63
    1642021-11-19  Brent Fulgham  <bfulgham@apple.com>
    265
  • trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.cpp

    r285121 r286075  
    4444}
    4545
     46void NetworkNotificationManager::maybeSendHostAppAuditToken() const
     47{
     48    if (m_sentHostAppAuditToken)
     49        return;
     50    m_sentHostAppAuditToken = true;
     51
     52#if PLATFORM(COCOA)
     53        auto token = m_networkSession.networkProcess().parentProcessConnection()->getAuditToken();
     54        if (!token)
     55            return;
     56
     57        Vector<uint8_t> auditTokenData;
     58        auditTokenData.resize(sizeof(*token));
     59        memcpy(auditTokenData.data(), &(*token), sizeof(*token));
     60
     61        sendMessage<WebPushD::MessageType::SetHostAppAuditToken>(auditTokenData);
     62#endif
     63}
     64
    4665void NetworkNotificationManager::requestSystemNotificationPermission(const String& originString, CompletionHandler<void(bool)>&& completionHandler)
    4766{
     
    104123{
    105124    RELEASE_ASSERT(m_connection);
     125
     126    maybeSendHostAppAuditToken();
     127
    106128    Daemon::Encoder encoder;
    107129    encoder.encode(std::forward<Args>(args)...);
     
    165187{
    166188    RELEASE_ASSERT(m_connection);
     189
     190    maybeSendHostAppAuditToken();
    167191
    168192    Daemon::Encoder encoder;
  • trunk/Source/WebKit/NetworkProcess/Notifications/NetworkNotificationManager.h

    r285121 r286075  
    6363    void didDestroyNotification(uint64_t notificationID) final;
    6464
     65    void maybeSendHostAppAuditToken() const;
     66
    6567    NetworkSession& m_networkSession;
    6668    std::unique_ptr<WebPushD::Connection> m_connection;
     69    mutable bool m_sentHostAppAuditToken { false };
    6770
    6871    template<WebPushD::MessageType messageType, typename... Args>
  • trunk/Source/WebKit/Resources/ios/XPCService-embedded-simulator.entitlements

    r265260 r286075  
    77        <key>com.apple.private.webkit.use-xpc-endpoint</key>
    88        <true/>
     9        <key>com.apple.private.webkit.webpush</key>
     10        <true/>
    911</dict>
    1012</plist>
  • trunk/Source/WebKit/Scripts/process-entitlements.sh

    r286032 r286075  
    132132        plistbuddy Add :com.apple.symptom_analytics.configure bool YES
    133133        plistbuddy Add :com.apple.private.webkit.adattributiond bool YES
     134        plistbuddy Add :com.apple.private.webkit.webpush bool YES
    134135    fi
    135136}
     
    402403{
    403404    plistbuddy Add :com.apple.private.webkit.adattributiond bool YES
     405    plistbuddy Add :com.apple.private.webkit.webpush bool YES
    404406    plistbuddy Add :com.apple.multitasking.systemappassertions bool YES
    405407    plistbuddy Add :com.apple.payment.all-access bool YES
  • trunk/Source/WebKit/Shared/Cocoa/CodeSigning.h

    r280451 r286075  
    3434String codeSigningIdentifierForCurrentProcess();
    3535String codeSigningIdentifier(xpc_connection_t);
     36String codeSigningIdentifier(audit_token_t);
    3637bool currentProcessIsPlatformBinary();
    3738std::pair<String, bool> codeSigningIdentifierAndPlatformBinaryStatus(xpc_connection_t);
  • trunk/Source/WebKit/Shared/Cocoa/CodeSigning.mm

    r280451 r286075  
    5858}
    5959
    60 std::pair<String, bool> codeSigningIdentifierAndPlatformBinaryStatus(xpc_connection_t connection)
     60static std::pair<String, bool> codeSigningIdentifierAndPlatformBinaryStatus(audit_token_t auditToken)
    6161{
    62     audit_token_t auditToken;
    63     xpc_connection_get_audit_token(connection, &auditToken);
    6462    auto task = adoptCF(SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken));
    6563    bool isPlatformBinary = SecTaskGetCodeSignStatus(task.get()) & CS_PLATFORM_BINARY;
     
    6866}
    6967
     68std::pair<String, bool> codeSigningIdentifierAndPlatformBinaryStatus(xpc_connection_t connection)
     69{
     70    audit_token_t auditToken;
     71    xpc_connection_get_audit_token(connection, &auditToken);
     72
     73    return codeSigningIdentifierAndPlatformBinaryStatus(auditToken);
     74}
     75
     76String codeSigningIdentifier(audit_token_t token)
     77{
     78    auto pair = codeSigningIdentifierAndPlatformBinaryStatus(token);
     79    return pair.first;
     80}
     81
    7082} // namespace WebKit
    7183
  • trunk/Source/WebKit/Shared/WebPushDaemonConstants.h

    r285121 r286075  
    4141    DeletePushAndNotificationRegistration,
    4242    GetOriginsWithPushAndNotificationPermissions,
     43    SetHostAppAuditToken,
     44    SetDebugModeIsEnabled,
    4345};
    4446
     
    5153    case MessageType::RequestSystemNotificationPermission:
    5254        return true;
     55    case MessageType::SetHostAppAuditToken:
     56    case MessageType::SetDebugModeIsEnabled:
     57        return false;
    5358    }
    5459    ASSERT_NOT_REACHED();
  • trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj

    r286067 r286075  
    10481048                51F060E11654318500F3282F /* WebMDNSRegisterMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3282F /* WebMDNSRegisterMessageReceiver.cpp */; };
    10491049                51F060E11654318500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F060DD1654317500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp */; };
     1050                51F7BB7B2744C50700C45A72 /* PushClientConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F7BB792744C50700C45A72 /* PushClientConnection.h */; };
     1051                51F7BB7C2744C50700C45A72 /* PushClientConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51F7BB7A2744C50700C45A72 /* PushClientConnection.mm */; };
     1052                51F7BB7D2745640400C45A72 /* CodeSigning.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE11AD4F1CBC47F800681EE5 /* CodeSigning.mm */; };
     1053                51F7BB7F274564A100C45A72 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F7BB7E274564A100C45A72 /* Security.framework */; };
    10501054                51F886A61F2C228100C193EF /* WKTestingSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F886A41F2C214A00C193EF /* WKTestingSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
    10511055                51FAEC3A1B0657630009C4E7 /* AuxiliaryProcessMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 51FAEC371B0657310009C4E7 /* AuxiliaryProcessMessages.h */; };
     
    42564260                51F060DD1654317500F3283F /* NetworkMDNSRegisterMessageReceiver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = NetworkMDNSRegisterMessageReceiver.cpp; path = DerivedSources/WebKit2/NetworkMDNSRegisterMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
    42574261                51F060DE1654317500F3281B /* WebResourceLoaderMessages.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebResourceLoaderMessages.h; path = DerivedSources/WebKit2/WebResourceLoaderMessages.h; sourceTree = BUILT_PRODUCTS_DIR; };
     4262                51F7BB792744C50700C45A72 /* PushClientConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PushClientConnection.h; sourceTree = "<group>"; };
     4263                51F7BB7A2744C50700C45A72 /* PushClientConnection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PushClientConnection.mm; sourceTree = "<group>"; };
     4264                51F7BB7E274564A100C45A72 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
    42584265                51F886A31F2C214A00C193EF /* WKTestingSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKTestingSupport.cpp; sourceTree = "<group>"; };
    42594266                51F886A41F2C214A00C193EF /* WKTestingSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKTestingSupport.h; sourceTree = "<group>"; };
     
    62306237                        buildActionMask = 2147483647;
    62316238                        files = (
     6239                                51F7BB7F274564A100C45A72 /* Security.framework in Frameworks */,
    62326240                        );
    62336241                        runOnlyForDeploymentPostprocessing = 0;
     
    93469354                        isa = PBXGroup;
    93479355                        children = (
     9356                                51F7BB7E274564A100C45A72 /* Security.framework */,
    93489357                                57A9FF15252C6AEF006A2040 /* libWTF.a */,
    93499358                                5750F32A2032D4E500389347 /* LocalAuthentication.framework */,
     
    95969605                        children = (
    95979606                                5CBB6D4D271F67CC00FD1A5D /* com.apple.webkit.webpushd.plist */,
     9607                                51F7BB792744C50700C45A72 /* PushClientConnection.h */,
     9608                                51F7BB7A2744C50700C45A72 /* PushClientConnection.mm */,
    95989609                                512CD69D2723393A00F7F8EC /* WebPushDaemon.h */,
    95999610                                512CD69E2723393A00F7F8EC /* WebPushDaemon.mm */,
     
    1206912080                        buildActionMask = 2147483647;
    1207012081                        files = (
     12082                                51F7BB7B2744C50700C45A72 /* PushClientConnection.h in Headers */,
    1207112083                                5C1579FC2717AF5000ED5280 /* DaemonUtilities.h in Headers */,
    1207212084                                512CD69F2723393A00F7F8EC /* WebPushDaemon.h in Headers */,
     
    1454714559                        buildActionMask = 2147483647;
    1454814560                        files = (
     14561                                51F7BB7D2745640400C45A72 /* CodeSigning.mm in Sources */,
    1454914562                                5C157A012717B7FB00ED5280 /* ArgumentCoders.cpp in Sources */,
    1455014563                                5C1579FF2717B6D200ED5280 /* DaemonDecoder.cpp in Sources */,
     14564                                51F7BB7C2744C50700C45A72 /* PushClientConnection.mm in Sources */,
    1455114565                                5C1579FE2717B6C100ED5280 /* DaemonEncoder.cpp in Sources */,
    1455214566                                5C1579FB2717AF5000ED5280 /* DaemonUtilities.mm in Sources */,
  • trunk/Source/WebKit/webpushd/PushClientConnection.h

    r286074 r286075  
    11/*
    2  * Copyright (C) 2016-2021 Apple Inc. All rights reserved.
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
     28#include <optional>
    2829#include <wtf/Forward.h>
     30#include <wtf/OSObjectPtr.h>
    2931#include <wtf/spi/darwin/XPCSPI.h>
     32#include <wtf/text/WTFString.h>
    3033
    31 namespace WebKit {
     34namespace WebPushD {
    3235
    33 // These functions return a null string if the process is unsigned.
    34 String codeSigningIdentifierForCurrentProcess();
    35 String codeSigningIdentifier(xpc_connection_t);
    36 bool currentProcessIsPlatformBinary();
    37 std::pair<String, bool> codeSigningIdentifierAndPlatformBinaryStatus(xpc_connection_t);
     36class ClientConnection {
     37    WTF_MAKE_FAST_ALLOCATED;
     38public:
     39    ClientConnection(xpc_connection_t);
    3840
    39 } // namespace WebKit
     41    bool hasHostAppAuditToken() const { return !!m_hostAppAuditToken; }
     42    void setHostAppAuditTokenData(const Vector<uint8_t>&);
     43
     44    const String& hostAppCodeSigningIdentifier();
     45    bool hostAppHasPushEntitlement();
     46
     47    bool debugModeIsEnabled() const { return m_debugModeEnabled; }
     48    void setDebugModeIsEnabled(bool);
     49
     50private:
     51    OSObjectPtr<xpc_connection_t> m_xpcConnection;
     52
     53    std::optional<audit_token_t> m_hostAppAuditToken;
     54    std::optional<String> m_hostAppCodeSigningIdentifier;
     55    std::optional<bool> m_hostAppHasPushEntitlement;
     56
     57    bool m_debugModeEnabled { false };
     58};
     59
     60} // namespace WebPushD
  • trunk/Source/WebKit/webpushd/WebPushDaemon.h

    r285121 r286075  
    2626#pragma once
    2727
     28#include "PushClientConnection.h"
    2829#include "WebPushDaemonConstants.h"
    2930#include <wtf/Forward.h>
     31#include <wtf/HashMap.h>
    3032#include <wtf/HashSet.h>
    3133#include <wtf/OSObjectPtr.h>
     
    3335#include <wtf/spi/darwin/XPCSPI.h>
    3436
    35 using WebKit::WebPushD::MessageType;
     37
     38namespace JSC {
     39enum class MessageLevel : uint8_t;
     40}
    3641
    3742namespace WebPushD {
     
    4954
    5055    // Message handlers
    51     void echoTwice(const String&, CompletionHandler<void(const String&)>&& replySender);
    52     void requestSystemNotificationPermission(const String&, CompletionHandler<void(bool)>&& replySender);
    53     void getOriginsWithPushAndNotificationPermissions(CompletionHandler<void(const Vector<String>&)>&& replySender);
    54     void deletePushAndNotificationRegistration(const String& originString, CompletionHandler<void(const String&)>&& replySender);
     56    void echoTwice(ClientConnection*, const String&, CompletionHandler<void(const String&)>&& replySender);
     57    void requestSystemNotificationPermission(ClientConnection*, const String&, CompletionHandler<void(bool)>&& replySender);
     58    void getOriginsWithPushAndNotificationPermissions(ClientConnection*, CompletionHandler<void(const Vector<String>&)>&& replySender);
     59    void deletePushAndNotificationRegistration(ClientConnection*, const String& originString, CompletionHandler<void(const String&)>&& replySender);
     60    void setHostAppAuditToken(ClientConnection*, const Vector<uint8_t>&);
     61    void setDebugModeIsEnabled(ClientConnection*, bool);
     62
     63    void broadcastDebugMessage(JSC::MessageLevel, const String&);
    5564
    5665private:
    5766    Daemon() = default;
    5867
    59     CompletionHandler<void(EncodedMessage&&)> createReplySender(MessageType, OSObjectPtr<xpc_object_t>&& request);
    60     void decodeAndHandleMessage(MessageType, Span<const uint8_t> encodedMessage, CompletionHandler<void(EncodedMessage&&)>&&);
     68    CompletionHandler<void(EncodedMessage&&)> createReplySender(WebKit::WebPushD::MessageType, OSObjectPtr<xpc_object_t>&& request);
     69    void decodeAndHandleMessage(xpc_connection_t, WebKit::WebPushD::MessageType, Span<const uint8_t> encodedMessage, CompletionHandler<void(EncodedMessage&&)>&&);
     70
     71    bool canRegisterForNotifications(ClientConnection&);
     72
     73    ClientConnection* toClientConnection(xpc_connection_t);
    6174
    6275    HashSet<String> m_inMemoryOriginStringsWithPermissionForTesting;
     76
     77    HashMap<xpc_connection_t, std::unique_ptr<ClientConnection>> m_connectionMap;
    6378};
    6479
  • trunk/Source/WebKit/webpushd/WebPushDaemon.mm

    r285121 r286075  
    6969END
    7070
     71FUNCTION(setHostAppAuditToken)
     72ARGUMENTS(Vector<uint8_t>)
     73END
     74
     75FUNCTION(setDebugModeIsEnabled)
     76ARGUMENTS(bool)
     77END
     78
    7179#undef FUNCTION
    7280#undef ARGUMENTS
     
    105113
    106114template<typename Info>
    107 void handleWebPushDMessageWithReply(Span<const uint8_t> encodedMessage, CompletionHandler<void(WebPushD::EncodedMessage&&)>&& replySender)
     115void handleWebPushDMessageWithReply(ClientConnection* connection, Span<const uint8_t> encodedMessage, CompletionHandler<void(WebPushD::EncodedMessage&&)>&& replySender)
    108116{
    109117    WebKit::Daemon::Decoder decoder(encodedMessage);
     
    118126    } };
    119127
    120     IPC::callMemberFunction(WTFMove(*arguments), WTFMove(completionHandler), &WebPushD::Daemon::singleton(), Info::MemberFunction);
     128    IPC::callMemberFunction(tuple_cat(std::make_tuple(connection), WTFMove(*arguments)), WTFMove(completionHandler), &WebPushD::Daemon::singleton(), Info::MemberFunction);
     129}
     130
     131template<typename Info>
     132void handleWebPushDMessage(ClientConnection* connection, Span<const uint8_t> encodedMessage)
     133{
     134    WebKit::Daemon::Decoder decoder(encodedMessage);
     135
     136    std::optional<typename Info::ArgsTuple> arguments;
     137    decoder >> arguments;
     138    if (UNLIKELY(!arguments))
     139        return;
     140
     141    IPC::callMemberFunction(tuple_cat(std::make_tuple(connection), WTFMove(*arguments)), &WebPushD::Daemon::singleton(), Info::MemberFunction);
    121142}
    122143
     
    125146    static NeverDestroyed<Daemon> daemon;
    126147    return daemon;
     148}
     149
     150void Daemon::broadcastDebugMessage(JSC::MessageLevel messageLevel, const String& message)
     151{
     152    auto dictionary = adoptOSObject(xpc_dictionary_create(nullptr, nullptr, 0));
     153    xpc_dictionary_set_uint64(dictionary.get(), protocolDebugMessageLevelKey, static_cast<uint64_t>(messageLevel));
     154    xpc_dictionary_set_string(dictionary.get(), protocolDebugMessageKey, message.utf8().data());
     155    for (auto& iterator : m_connectionMap) {
     156        if (iterator.value->debugModeIsEnabled())
     157            xpc_connection_send_message(iterator.key, dictionary.get());
     158    }
    127159}
    128160
     
    143175    Span<const uint8_t> encodedMessage { static_cast<const uint8_t*>(data), dataSize };
    144176   
    145     decodeAndHandleMessage(messageType, encodedMessage, createReplySender(messageType, request));
    146 }
    147 
    148 void Daemon::connectionAdded(xpc_connection_t)
    149 {
    150     // FIXME: Track connections
    151 }
    152 
    153 void Daemon::connectionRemoved(xpc_connection_t)
    154 {
    155     // FIXME: Track connections
     177    decodeAndHandleMessage(xpc_dictionary_get_remote_connection(request), messageType, encodedMessage, createReplySender(messageType, request));
     178}
     179
     180void Daemon::connectionAdded(xpc_connection_t connection)
     181{
     182    RELEASE_ASSERT(!m_connectionMap.contains(connection));
     183    m_connectionMap.set(connection, WTF::makeUnique<ClientConnection>(connection));
     184}
     185
     186void Daemon::connectionRemoved(xpc_connection_t connection)
     187{
     188    RELEASE_ASSERT(m_connectionMap.contains(connection));
     189    m_connectionMap.remove(connection);
    156190}
    157191
     
    170204}
    171205
    172 void Daemon::decodeAndHandleMessage(MessageType messageType, Span<const uint8_t> encodedMessage, CompletionHandler<void(EncodedMessage&&)>&& replySender)
     206void Daemon::decodeAndHandleMessage(xpc_connection_t connection, MessageType messageType, Span<const uint8_t> encodedMessage, CompletionHandler<void(EncodedMessage&&)>&& replySender)
    173207{
    174208    ASSERT(messageTypeSendsReply(messageType) == !!replySender);
     209
     210    auto* clientConnection = toClientConnection(connection);
    175211
    176212    switch (messageType) {
    177213    case MessageType::EchoTwice:
    178         handleWebPushDMessageWithReply<MessageInfo::echoTwice>(encodedMessage, WTFMove(replySender));
     214        handleWebPushDMessageWithReply<MessageInfo::echoTwice>(clientConnection, encodedMessage, WTFMove(replySender));
    179215        break;
    180216    case MessageType::GetOriginsWithPushAndNotificationPermissions:
    181         handleWebPushDMessageWithReply<MessageInfo::getOriginsWithPushAndNotificationPermissions>(encodedMessage, WTFMove(replySender));
     217        handleWebPushDMessageWithReply<MessageInfo::getOriginsWithPushAndNotificationPermissions>(clientConnection, encodedMessage, WTFMove(replySender));
    182218        break;
    183219    case MessageType::DeletePushAndNotificationRegistration:
    184         handleWebPushDMessageWithReply<MessageInfo::deletePushAndNotificationRegistration>(encodedMessage, WTFMove(replySender));
     220        handleWebPushDMessageWithReply<MessageInfo::deletePushAndNotificationRegistration>(clientConnection, encodedMessage, WTFMove(replySender));
    185221        break;
    186222    case MessageType::RequestSystemNotificationPermission:
    187         handleWebPushDMessageWithReply<MessageInfo::requestSystemNotificationPermission>(encodedMessage, WTFMove(replySender));
    188         break;
    189     }
    190 }
    191 
    192 void Daemon::echoTwice(const String& message, CompletionHandler<void(const String&)>&& replySender)
     223        handleWebPushDMessageWithReply<MessageInfo::requestSystemNotificationPermission>(clientConnection, encodedMessage, WTFMove(replySender));
     224        break;
     225    case MessageType::SetHostAppAuditToken:
     226        handleWebPushDMessage<MessageInfo::setHostAppAuditToken>(clientConnection, encodedMessage);
     227        break;
     228    case MessageType::SetDebugModeIsEnabled:
     229        handleWebPushDMessage<MessageInfo::setDebugModeIsEnabled>(clientConnection, encodedMessage);
     230        break;
     231    }
     232}
     233
     234void Daemon::echoTwice(ClientConnection*, const String& message, CompletionHandler<void(const String&)>&& replySender)
    193235{
    194236    replySender(makeString(message, message));
    195237}
    196238
    197 void Daemon::requestSystemNotificationPermission(const String& originString, CompletionHandler<void(bool)>&& replySender)
    198 {
     239bool Daemon::canRegisterForNotifications(ClientConnection& connection)
     240{
     241    if (connection.hostAppCodeSigningIdentifier().isEmpty()) {
     242        NSLog(@"ClientConnection cannot interact with notifications: Unknown host application code signing identifier");
     243        return false;
     244    }
     245
     246    return true;
     247}
     248
     249void Daemon::requestSystemNotificationPermission(ClientConnection* connection, const String& originString, CompletionHandler<void(bool)>&& replySender)
     250{
     251    if (!canRegisterForNotifications(*connection)) {
     252        replySender(false);
     253        return;
     254    }
     255
    199256    // FIXME: This is for an API testing checkpoint
    200257    // Next step is actually perform a persistent permissions request on a per-platform basis
     
    203260}
    204261
    205 void Daemon::getOriginsWithPushAndNotificationPermissions(CompletionHandler<void(const Vector<String>&)>&& replySender)
    206 {
     262void Daemon::getOriginsWithPushAndNotificationPermissions(ClientConnection* connection, CompletionHandler<void(const Vector<String>&)>&& replySender)
     263{
     264    if (!canRegisterForNotifications(*connection)) {
     265        replySender({ });
     266        return;
     267    }
     268
    207269    // FIXME: This is for an API testing checkpoint
    208270    // Next step is actually gather persistent permissions from the system on a per-platform basis
     
    210272}
    211273
    212 void Daemon::deletePushAndNotificationRegistration(const String& originString, CompletionHandler<void(const String&)>&& replySender)
    213 {
     274void Daemon::deletePushAndNotificationRegistration(ClientConnection* connection, const String& originString, CompletionHandler<void(const String&)>&& replySender)
     275{
     276    if (!canRegisterForNotifications(*connection)) {
     277        replySender("Could not delete push and notification registrations for connection: Unknown host application code signing identifier");
     278        return;
     279    }
     280
    214281    // FIXME: This is for an API testing checkpoint
    215282    // Next step is actually delete any persistent permissions on a per-platform basis
     
    220287}
    221288
     289void Daemon::setHostAppAuditToken(ClientConnection* clientConnection, const Vector<uint8_t>& tokenData)
     290{
     291    clientConnection->setHostAppAuditTokenData(tokenData);
     292}
     293
     294void Daemon::setDebugModeIsEnabled(ClientConnection* clientConnection, bool enabled)
     295{
     296    clientConnection->setDebugModeIsEnabled(enabled);
     297}
     298
     299ClientConnection* Daemon::toClientConnection(xpc_connection_t connection)
     300{
     301    auto clientConnection = m_connectionMap.get(connection);
     302    RELEASE_ASSERT(clientConnection);
     303    return clientConnection;
     304}
     305
    222306} // namespace WebPushD
  • trunk/Source/WebKit/webpushd/WebPushDaemonMain.mm

    r284887 r286075  
    6565
    6666    @autoreleasepool {
    67         // FIXME: Add a sandbox.
    68         // FIXME: Add an entitlement check.
    69         WebKit::startListeningForMachServiceConnections(machServiceName, nullptr, WebPushD::connectionAdded, WebPushD::connectionRemoved, WebPushD::connectionEventHandler);
     67        WebKit::startListeningForMachServiceConnections(machServiceName, "com.apple.private.webkit.webpush", WebPushD::connectionAdded, WebPushD::connectionRemoved, WebPushD::connectionEventHandler);
    7068        WTF::initializeMainThread();
    7169    }
  • trunk/Tools/ChangeLog

    r286074 r286075  
     12021-11-19  Brady Eidson  <beidson@apple.com>
     2
     3        More webpushd architecture work
     4        https://bugs.webkit.org/show_bug.cgi?id=233295
     5
     6        Reviewed by Alex Christensen.
     7
     8        * TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements:
     9        * TestWebKitAPI/Configurations/TestWebKitAPI-macOS-internal.entitlements:
     10        * TestWebKitAPI/Configurations/TestWebKitAPI-macOS.entitlements:
     11        * TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm:
     12        (TestWebKitAPI::TEST):
     13
    1142021-11-18  Jonathan Bedard  <jbedard@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements

    r285799 r286075  
    1111        <key>com.apple.Pasteboard.paste-unchecked</key>
    1212        <true/>
     13        <key>com.apple.private.webkit.webpush</key>
     14        <true/>
    1315        <key>com.apple.private.xpc.launchd.job-manager</key>
    1416        <string>TestWebKitAPI</string>
  • trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-macOS-internal.entitlements

    r282368 r286075  
    55        <key>com.apple.private.xpc.launchd.job-manager</key>
    66        <string>TestWebKitAPI</string>
     7        <key>com.apple.private.webkit.webpush</key>
     8        <true/>
    79        <key>com.apple.hid.manager.user-access-device</key>
    810        <true/>
  • trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-macOS.entitlements

    r282368 r286075  
    99                <string>com.apple.TestWebKitAPI</string>
    1010        </array>
     11        <key>com.apple.private.webkit.webpush</key>
     12        <true/>
    1113        <key>com.apple.security.temporary-exception.sbpl</key>
    1214        <array>
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm

    r285963 r286075  
    3232#import <WebKit/WKUIDelegatePrivate.h>
    3333#import <WebKit/_WKExperimentalFeature.h>
     34#import <mach/mach_init.h>
     35#import <mach/task.h>
    3436
    3537#if PLATFORM(MAC) || PLATFORM(IOS)
     
    157159
    158160// FIXME: Re-enable this test for Monterey+ once webkit.org/232857 is resolved.
    159 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
     161#if __MAC_OS_X_VERSION_MIN_REQUIRED < 110000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
    160162TEST(WebPushD, DISABLED_BasicCommunication)
    161163#else
     
    166168
    167169    auto connection = adoptNS(xpc_connection_create_mach_service("org.webkit.webpushtestdaemon.service", dispatch_get_main_queue(), 0));
    168     xpc_connection_set_event_handler(connection.get(), ^(xpc_object_t) { });
     170
     171    __block bool done = false;
     172    xpc_connection_set_event_handler(connection.get(), ^(xpc_object_t request) {
     173        if (xpc_get_type(request) != XPC_TYPE_DICTIONARY)
     174            return;
     175        const char* debugMessage = xpc_dictionary_get_string(request, "debug message");
     176        if (!debugMessage)
     177            return;
     178
     179        bool stringMatches = !strcmp(debugMessage, "[webpushd - TestWebKitAPI] Turned Debug Mode on");
     180        if (!stringMatches)
     181            stringMatches = !strcmp(debugMessage, "[webpushd - com.apple.WebKit.TestWebKitAPI] Turned Debug Mode on");
     182
     183        EXPECT_TRUE(stringMatches);
     184
     185        done = true;
     186    });
     187
    169188    xpc_connection_activate(connection.get());
     189
     190    audit_token_t token = { 0, 0, 0, 0, 0, 0, 0, 0 };
     191    mach_msg_type_number_t auditTokenCount = TASK_AUDIT_TOKEN_COUNT;
     192    kern_return_t result = task_info(mach_task_self(), TASK_AUDIT_TOKEN, (task_info_t)(&token), &auditTokenCount);
     193    if (result != KERN_SUCCESS) {
     194        EXPECT_TRUE(false);
     195        return;
     196    }
     197
     198    // Send audit token
     199    {
     200        std::array<uint8_t, 40> encodedMessage;
     201        encodedMessage.fill(0);
     202        encodedMessage[0] = 32;
     203        memcpy(&encodedMessage[8], &token, sizeof(token));
     204        auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
     205        xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1);
     206        xpc_dictionary_set_uint64(dictionary.get(), "message type", 5);
     207        xpc_dictionary_set_data(dictionary.get(), "encoded message", encodedMessage.data(), encodedMessage.size());
     208        xpc_connection_send_message(connection.get(), dictionary.get());
     209    }
     210
     211    // Enable debug messages, and wait for the resulting debug message
     212    {
     213        auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
     214        std::array<uint8_t, 1> encodedMessage { 1 };
     215        xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1);
     216        xpc_dictionary_set_uint64(dictionary.get(), "message type", 6);
     217        xpc_dictionary_set_data(dictionary.get(), "encoded message", encodedMessage.data(), encodedMessage.size());
     218
     219        xpc_connection_send_message(connection.get(), dictionary.get());
     220        TestWebKitAPI::Util::run(&done);
     221    }
     222
     223    // Echo and wait for a reply
    170224    auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
    171 
    172225    std::array<uint8_t, 10> encodedString { 5, 0, 0, 0, 1, 'h', 'e', 'l', 'l', 'o' };
    173226    xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1);
    174227    xpc_dictionary_set_uint64(dictionary.get(), "message type", 1);
    175228    xpc_dictionary_set_data(dictionary.get(), "encoded message", encodedString.data(), encodedString.size());
    176    
    177     __block bool done = false;
     229
     230    done = false;
    178231    xpc_connection_send_message_with_reply(connection.get(), dictionary.get(), dispatch_get_main_queue(), ^(xpc_object_t reply) {
    179232        if (xpc_get_type(reply) != XPC_TYPE_DICTIONARY) {
     
    203256
    204257// FIXME: Re-enable this test for Monterey+ once webkit.org/232857 is resolved.
    205 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
     258#if __MAC_OS_X_VERSION_MIN_REQUIRED < 110000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 120000
    206259TEST(WebPushD, DISABLED_PermissionManagement)
    207260#else
Note: See TracChangeset for help on using the changeset viewer.