source: webkit/trunk/Source/WebKit/webpushd/webpushtool/WebPushToolConnection.mm@ 286777

Last change on this file since 286777 was 286777, checked in by commit-queue@webkit.org, 3 years ago

Unreviewed, reverting r286764.
https://bugs.webkit.org/show_bug.cgi?id=234081

broke the build

Reverted changeset:

"Add ability to inject messages into webpushd"
https://bugs.webkit.org/show_bug.cgi?id=233988
https://commits.webkit.org/r286764

File size: 5.9 KB
Line 
1/*
2 * Copyright (C) 2021 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#import "config.h"
27#import "WebPushToolConnection.h"
28
29#import <mach/mach_init.h>
30#import <mach/task.h>
31#import <pal/spi/cocoa/ServersSPI.h>
32#import <wtf/MainThread.h>
33#import <wtf/RetainPtr.h>
34
35namespace WebPushTool {
36
37std::unique_ptr<Connection> Connection::create(Action action, PreferTestService preferTestService, Reconnect reconnect)
38{
39 return makeUnique<Connection>(action, preferTestService, reconnect);
40}
41
42static mach_port_t maybeConnectToService(const char* serviceName)
43{
44 mach_port_t bsPort;
45 task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT, &bsPort);
46
47 mach_port_t servicePort;
48 kern_return_t err = bootstrap_look_up(bsPort, serviceName, &servicePort);
49
50 if (err == KERN_SUCCESS)
51 return servicePort;
52
53 return MACH_PORT_NULL;
54}
55
56Connection::Connection(Action action, PreferTestService preferTestService, Reconnect reconnect)
57 : m_action(action)
58 , m_reconnect(reconnect == Reconnect::Yes)
59{
60 if (preferTestService == PreferTestService::Yes)
61 m_serviceName = "org.webkit.webpushtestdaemon.service";
62 else
63 m_serviceName = "com.apple.webkit.webpushd.service";
64}
65
66void Connection::connectToService()
67{
68 if (m_connection)
69 return;
70
71 m_connection = adoptNS(xpc_connection_create_mach_service(m_serviceName, dispatch_get_main_queue(), 0));
72
73 xpc_connection_set_event_handler(m_connection.get(), [this, weakThis = WeakPtr { *this }](xpc_object_t event) {
74 if (!weakThis)
75 return;
76
77 if (event == XPC_ERROR_CONNECTION_INVALID) {
78 printf("Failed to start listening for connections to mach service\n");
79 connectionDropped();
80 return;
81 }
82
83 if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
84 printf("Connection closed\n");
85 if (m_reconnect)
86 printf("===============\nReconnecting...\n");
87 connectionDropped();
88 return;
89 }
90
91 if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) {
92 messageReceived(event);
93 return;
94 }
95
96 RELEASE_ASSERT_NOT_REACHED();
97 });
98
99 auto result = maybeConnectToService(m_serviceName);
100 if (result == MACH_PORT_NULL)
101 printf("Waiting for service '%s' to be available\n", m_serviceName);
102
103 while (result == MACH_PORT_NULL) {
104 usleep(1000);
105 result = maybeConnectToService(m_serviceName);
106 }
107
108 xpc_connection_activate(m_connection.get());
109
110 sendAuditToken();
111 startAction();
112}
113
114void Connection::startAction()
115{
116 switch (m_action) {
117 case Action::StreamDebugMessages:
118 startDebugStreamAction();
119 break;
120 };
121}
122
123void Connection::startDebugStreamAction()
124{
125 auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
126 std::array<uint8_t, 1> encodedMessage { 1 };
127 xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1);
128 xpc_dictionary_set_uint64(dictionary.get(), "message type", 5);
129 xpc_dictionary_set_data(dictionary.get(), "encoded message", encodedMessage.data(), encodedMessage.size());
130
131 xpc_connection_send_message(m_connection.get(), dictionary.get());
132
133 printf("Now streaming debug messages\n");
134}
135
136void Connection::sendAuditToken()
137{
138 audit_token_t token = { 0, 0, 0, 0, 0, 0, 0, 0 };
139 mach_msg_type_number_t auditTokenCount = TASK_AUDIT_TOKEN_COUNT;
140 kern_return_t result = task_info(mach_task_self(), TASK_AUDIT_TOKEN, (task_info_t)(&token), &auditTokenCount);
141 if (result != KERN_SUCCESS) {
142 printf("Unable to get audit token to send\n");
143 return;
144 }
145
146 std::array<uint8_t, 42> encodedMessage;
147 encodedMessage.fill(0);
148 encodedMessage[1] = 1;
149 encodedMessage[2] = 32;
150 memcpy(&encodedMessage[10], &token, sizeof(token));
151 auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));
152 xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1);
153 xpc_dictionary_set_uint64(dictionary.get(), "message type", 6);
154 xpc_dictionary_set_data(dictionary.get(), "encoded message", encodedMessage.data(), encodedMessage.size());
155 xpc_connection_send_message(m_connection.get(), dictionary.get());
156}
157
158void Connection::connectionDropped()
159{
160 m_connection = nullptr;
161 if (m_reconnect) {
162 callOnMainRunLoop([this, weakThis = WeakPtr { this }] {
163 if (weakThis)
164 connectToService();
165 });
166 return;
167 }
168
169 CFRunLoopStop(CFRunLoopGetCurrent());
170}
171
172void Connection::messageReceived(xpc_object_t message)
173{
174 const char* debugMessage = xpc_dictionary_get_string(message, "debug message");
175 if (!debugMessage)
176 return;
177
178 printf("%s\n", debugMessage);
179}
180
181} // namespace WebPushTool
Note: See TracBrowser for help on using the repository browser.