File indexing completed on 2024-11-10 04:57:32
0001 /* 0002 SPDX-FileCopyrightText: 2023 David Edmundson <davidedmundson@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "securitycontext_v1.h" 0007 #include "display.h" 0008 #include "utils/filedescriptor.h" 0009 #include "wayland/display_p.h" 0010 0011 #include <qwayland-server-security-context-v1.h> 0012 0013 #include <QDebug> 0014 0015 class QSocketNotifier; 0016 0017 namespace KWin 0018 { 0019 static const quint32 s_version = 1; 0020 0021 class SecurityContextManagerV1InterfacePrivate : public QtWaylandServer::wp_security_context_manager_v1 0022 { 0023 public: 0024 SecurityContextManagerV1InterfacePrivate(Display *display); 0025 0026 protected: 0027 void wp_security_context_manager_v1_destroy(Resource *resource) override; 0028 void wp_security_context_manager_v1_create_listener(Resource *resource, uint32_t id, int32_t listen_fd, int32_t close_fd) override; 0029 0030 private: 0031 Display *m_display; 0032 }; 0033 0034 class SecurityContextV1Interface : public QtWaylandServer::wp_security_context_v1 0035 { 0036 public: 0037 SecurityContextV1Interface(Display *display, int listenFd, int closeFd, wl_resource *resource); 0038 0039 protected: 0040 void wp_security_context_v1_set_sandbox_engine(Resource *resource, const QString &name) override; 0041 void wp_security_context_v1_set_app_id(Resource *resource, const QString &app_id) override; 0042 void wp_security_context_v1_set_instance_id(Resource *resource, const QString &instance_id) override; 0043 void wp_security_context_v1_commit(Resource *resource) override; 0044 void wp_security_context_v1_destroy_resource(Resource *resource) override; 0045 void wp_security_context_v1_destroy(Resource *resource) override; 0046 0047 private: 0048 Display *m_display; 0049 FileDescriptor m_listenFd; 0050 FileDescriptor m_closeFd; 0051 bool m_committed = false; 0052 QString m_sandboxEngine; 0053 QString m_appId; 0054 QString m_instanceId; 0055 }; 0056 0057 SecurityContextManagerV1Interface::SecurityContextManagerV1Interface(Display *display, QObject *parent) 0058 : QObject(parent) 0059 , d(new SecurityContextManagerV1InterfacePrivate(display)) 0060 { 0061 } 0062 0063 SecurityContextManagerV1Interface::~SecurityContextManagerV1Interface() 0064 { 0065 } 0066 0067 SecurityContextManagerV1InterfacePrivate::SecurityContextManagerV1InterfacePrivate(Display *display) 0068 : QtWaylandServer::wp_security_context_manager_v1(*display, s_version) 0069 , m_display(display) 0070 { 0071 } 0072 0073 void SecurityContextManagerV1InterfacePrivate::wp_security_context_manager_v1_destroy(Resource *resource) 0074 { 0075 wl_resource_destroy(resource->handle); 0076 } 0077 0078 void SecurityContextManagerV1InterfacePrivate::wp_security_context_manager_v1_create_listener(Resource *resource, uint32_t id, int32_t listen_fd, int32_t close_fd) 0079 { 0080 auto *securityContextResource = wl_resource_create(resource->client(), &wp_security_context_v1_interface, resource->version(), id); 0081 if (!securityContextResource) { 0082 wl_resource_post_no_memory(resource->handle); 0083 return; 0084 } 0085 new SecurityContextV1Interface(m_display, listen_fd, close_fd, securityContextResource); 0086 } 0087 0088 SecurityContextV1Interface::SecurityContextV1Interface(Display *display, int listenFd, int closeFd, wl_resource *resource) 0089 : QtWaylandServer::wp_security_context_v1(resource) 0090 , m_display(display) 0091 , m_listenFd(listenFd) 0092 , m_closeFd(closeFd) 0093 { 0094 } 0095 0096 void SecurityContextV1Interface::wp_security_context_v1_set_sandbox_engine(Resource *resource, const QString &name) 0097 { 0098 if (m_committed) { 0099 wl_resource_post_error(resource->handle, error_already_used, "Already committed"); 0100 return; 0101 } 0102 m_sandboxEngine = name; 0103 } 0104 0105 void SecurityContextV1Interface::wp_security_context_v1_set_app_id(Resource *resource, const QString &app_id) 0106 { 0107 if (m_committed) { 0108 wl_resource_post_error(resource->handle, error_already_used, "Already committed"); 0109 return; 0110 } 0111 if (app_id.isEmpty()) { 0112 wl_resource_post_error(resource->handle, error_invalid_metadata, "App ID cannot be empty"); 0113 return; 0114 } 0115 m_appId = app_id; 0116 } 0117 0118 void SecurityContextV1Interface::wp_security_context_v1_set_instance_id(Resource *resource, const QString &instance_id) 0119 { 0120 if (m_committed) { 0121 wl_resource_post_error(resource->handle, error_already_used, "Already committed"); 0122 return; 0123 } 0124 m_instanceId = instance_id; 0125 } 0126 0127 void SecurityContextV1Interface::wp_security_context_v1_commit(Resource *resource) 0128 { 0129 if (m_committed) { 0130 wl_resource_post_error(resource->handle, error_already_used, "Already committed"); 0131 return; 0132 } 0133 if (m_appId.isEmpty()) { 0134 wl_resource_post_error(resource->handle, error_invalid_metadata, "App ID cannot be empty"); 0135 return; 0136 } 0137 if (m_sandboxEngine.isEmpty()) { 0138 wl_resource_post_error(resource->handle, error_invalid_metadata, "Sandbox engine cannot be empty"); 0139 return; 0140 } 0141 0142 m_committed = true; 0143 0144 // lifespan is managed by the closeFD's state 0145 new SecurityContext(m_display, std::move(m_listenFd), std::move(m_closeFd), m_appId); 0146 } 0147 0148 void SecurityContextV1Interface::wp_security_context_v1_destroy_resource(Resource *resource) 0149 { 0150 delete this; 0151 } 0152 0153 void SecurityContextV1Interface::wp_security_context_v1_destroy(Resource *resource) 0154 { 0155 wl_resource_destroy(resource->handle); 0156 } 0157 0158 }