]> git.mdlowis.com Git - proto/labwc.git/commitdiff
wayland: add support for security-context-v1
authorYuri Nesterov <yuriy.nesterov@unikie.com>
Thu, 16 May 2024 09:52:47 +0000 (12:52 +0300)
committerJohan Malm <johanmalm@users.noreply.github.com>
Wed, 29 May 2024 21:28:06 +0000 (22:28 +0100)
docs/labwc-config.5.scd
docs/rc.xml.all
include/labwc.h
include/view.h
include/window-rules.h
src/config/rcxml.c
src/server.c
src/view.c
src/window-rules.c

index 26cefdb2c4f3d5c78851e5951439f46366dd6ef9..7d8982dcd59b740b7c9752c2bd488df540c7f30a 100644 (file)
@@ -851,7 +851,8 @@ defined as shown below.
 
 *Criteria*
 
-*<windowRules><windowRule identifier="" title="" type="" matchOnce="">*
+*<windowRules><windowRule identifier="" title="" sandboxEngine=""
+sandboxAppId="" type="" matchOnce="">*
        Define a window rule for any window which matches the criteria defined
        by the attributes *identifier*, *title*, or *type*. If more than one
        is defined, AND logic is used, so all have to match.
@@ -863,6 +864,11 @@ defined as shown below.
 
        *title* is the title of the window.
 
+       *sandboxEngine* is a sandbox engine name from the security context.
+
+       *sandboxAppId* is a sandbox-specific identifier for an application
+       from the security context.
+
        *type* [desktop|dock|toolbar|menu|utility|splash|dialog|dropdown_menu|
        popup_menu|tooltip|notification|combo|dnd|normal] relates to
        NET_WM_WINDOW_TYPE for XWayland clients. Native wayland clients have
index a8f9f3a019ad8ff28e4ff4be0bf917fb57fbc560..a4e70efb70e07f889b4c13f17eecdc95b4fdbbdd 100644 (file)
 
   <!--
     # Window Rules
-    #   - Criteria can consist of 'identifier' or 'title' or both (in which
-    #     case AND logic is used).
+    #   - Criteria can consist of 'identifier', 'title', 'sandboxEngine' or
+    #     'sandboxAppId'. AND logic is used when multiple options are specified.
     #   - 'identifier' relates to app_id for native Wayland windows and
     #     WM_CLASS for XWayland clients.
     #   - Criteria can also contain `matchOnce="true"` meaning that the rule
index 8f26887aa0e0c2aaef2cad1af4cd47ef82b03fe8..ed858e64fa573d8c83f186477b80909e4a0befd6 100644 (file)
@@ -335,6 +335,7 @@ struct server {
        struct wlr_text_input_manager_v3 *text_input_manager;
 
        struct wlr_tablet_manager_v2 *tablet_manager;
+       struct wlr_security_context_manager_v1 *security_context_manager_v1;
 
        /* Set when in cycle (alt-tab) mode */
        struct osd_state {
index c236627814b57975f91d586a329ff7f16b87aff3..141038d33ce1b28e6b2968bcb93149f5c4d748d8 100644 (file)
@@ -267,6 +267,8 @@ struct view_query {
        char *identifier;
        char *title;
        int window_type;
+       char *sandbox_engine;
+       char *sandbox_app_id;
 };
 
 struct xdg_toplevel_view {
index 17c5dca3789c5df4b25611a7c85a9580e3f180e8..b93bc367b3dadd6601b65efa06cbbbe18c0088f0 100644 (file)
@@ -25,6 +25,8 @@ struct window_rule {
        char *identifier;
        char *title;
        int window_type;
+       char *sandbox_engine;
+       char *sandbox_app_id;
        bool match_once;
 
        enum window_rule_event event;
index 741938a9ac77eb4976d315d7d02105a273795151..4f3db549b94ee0e15dd3c3bbdde787eb0bda13eb 100644 (file)
@@ -189,6 +189,12 @@ fill_window_rule(char *nodename, char *content)
                current_window_rule->window_type = parse_window_type(content);
        } else if (!strcasecmp(nodename, "matchOnce")) {
                set_bool(content, &current_window_rule->match_once);
+       } else if (!strcasecmp(nodename, "sandboxEngine")) {
+               free(current_window_rule->sandbox_engine);
+               current_window_rule->sandbox_engine = xstrdup(content);
+       } else if (!strcasecmp(nodename, "sandboxAppId")) {
+               free(current_window_rule->sandbox_app_id);
+               current_window_rule->sandbox_app_id = xstrdup(content);
 
        /* Event */
        } else if (!strcmp(nodename, "event")) {
@@ -323,6 +329,10 @@ fill_action_query(char *nodename, char *content, struct action *action)
                current_view_query->title = xstrdup(content);
        } else if (!strcmp(nodename, "type")) {
                current_view_query->window_type = parse_window_type(content);
+       } else if (!strcasecmp(nodename, "sandboxEngine")) {
+               current_view_query->sandbox_engine = xstrdup(content);
+       } else if (!strcasecmp(nodename, "sandboxAppId")) {
+               current_view_query->sandbox_app_id = xstrdup(content);
        }
 }
 
@@ -1508,6 +1518,8 @@ rule_destroy(struct window_rule *rule)
        wl_list_remove(&rule->link);
        zfree(rule->identifier);
        zfree(rule->title);
+       zfree(rule->sandbox_engine);
+       zfree(rule->sandbox_app_id);
        action_list_free(&rule->actions);
        zfree(rule);
 }
@@ -1576,7 +1588,8 @@ validate(void)
        /* Window-rule criteria */
        struct window_rule *rule, *rule_tmp;
        wl_list_for_each_safe(rule, rule_tmp, &rc.window_rules, link) {
-               if (!rule->identifier && !rule->title && rule->window_type < 0) {
+               if (!rule->identifier && !rule->title && rule->window_type < 0
+                               && !rule->sandbox_engine && !rule->sandbox_app_id) {
                        wlr_log(WLR_ERROR, "Deleting rule %p as it has no criteria", rule);
                        rule_destroy(rule);
                }
index 87cbd9e7022d38cd8af3a6ebf940c8be390a3c28..0a093930d63e40922a6af74ae17c90ab61982d4e 100644 (file)
@@ -14,6 +14,7 @@
 #include <wlr/types/wlr_presentation_time.h>
 #include <wlr/types/wlr_primary_selection_v1.h>
 #include <wlr/types/wlr_screencopy_v1.h>
+#include <wlr/types/wlr_security_context_v1.h>
 #include <wlr/types/wlr_single_pixel_buffer_v1.h>
 #include <wlr/types/wlr_viewporter.h>
 #include <wlr/types/wlr_tablet_v2.h>
@@ -261,6 +262,15 @@ server_global_filter(const struct wl_client *client, const struct wl_global *glo
        }
 #endif
 
+       /* Do not allow security_context_manager_v1 to clients with a security context attached */
+       const struct wlr_security_context_v1_state *security_context =
+               wlr_security_context_manager_v1_lookup_client(
+                       server->security_context_manager_v1, (struct wl_client *)client);
+       if (security_context && global == server->security_context_manager_v1->global) {
+               wlr_log(WLR_DEBUG, "blocking security_context_manager_v1 for the sandboxed client");
+               return false;
+       }
+
        return true;
 }
 
@@ -493,6 +503,8 @@ server_init(struct server *server)
        wlr_export_dmabuf_manager_v1_create(server->wl_display);
        wlr_screencopy_manager_v1_create(server->wl_display);
        wlr_data_control_manager_v1_create(server->wl_display);
+       server->security_context_manager_v1 =
+               wlr_security_context_manager_v1_create(server->wl_display);
        wlr_viewporter_create(server->wl_display);
        wlr_single_pixel_buffer_manager_v1_create(server->wl_display);
        wlr_fractional_scale_manager_v1_create(server->wl_display,
index d4bb1f0f93ba30ee3e8dcfa8d9116f1b146671b8..ab106208f0bcb83b4b267fab34d1b496d717a4e9 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <strings.h>
 #include <wlr/types/wlr_output_layout.h>
+#include <wlr/types/wlr_security_context_v1.h>
 #include "common/macros.h"
 #include "common/match.h"
 #include "common/mem.h"
@@ -53,6 +54,17 @@ view_from_wlr_surface(struct wlr_surface *surface)
        return NULL;
 }
 
+static const struct wlr_security_context_v1_state *
+security_context_from_view(struct view *view)
+{
+       if (view && view->surface && view->surface->resource) {
+               struct wl_client *client = wl_resource_get_client(view->surface->resource);
+               return wlr_security_context_manager_v1_lookup_client(
+                       view->server->security_context_manager_v1, client);
+       }
+       return NULL;
+}
+
 struct view_query *
 view_query_create(void)
 {
@@ -67,6 +79,8 @@ view_query_free(struct view_query *query)
        wl_list_remove(&query->link);
        free(query->identifier);
        free(query->title);
+       free(query->sandbox_engine);
+       free(query->sandbox_app_id);
        free(query);
 }
 
@@ -93,6 +107,22 @@ view_matches_query(struct view *view, struct view_query *query)
                match &= view_contains_window_type(view, query->window_type);
        }
 
+       if (match && query->sandbox_engine) {
+               const struct wlr_security_context_v1_state *security_context =
+                       security_context_from_view(view);
+               empty = false;
+               match &= security_context && security_context->sandbox_engine
+                       && match_glob(query->sandbox_engine, security_context->sandbox_engine);
+       }
+
+       if (match && query->sandbox_app_id) {
+               const struct wlr_security_context_v1_state *security_context =
+                       security_context_from_view(view);
+               empty = false;
+               match &= security_context && security_context->app_id
+                       && match_glob(query->sandbox_app_id, security_context->app_id);
+       }
+
        return !empty && match;
 }
 
index 95d0a1ddb588f3fe7de221c90630bc92e85977bb..f543f7ec8f28649e3508d4f7a705e613a3fa4f80 100644 (file)
@@ -34,6 +34,8 @@ view_matches_criteria(struct window_rule *rule, struct view *view)
        query.identifier = rule->identifier;
        query.title = rule->title;
        query.window_type = rule->window_type;
+       query.sandbox_engine = rule->sandbox_engine;
+       query.sandbox_app_id = rule->sandbox_app_id;
 
        if (rule->match_once && other_instances_exist(view, &query)) {
                return false;