wayland: add support for security-context-v1

This commit is contained in:
Yuri Nesterov 2024-05-16 12:52:47 +03:00 committed by Johan Malm
parent 15135465d9
commit 65f7499f1c
9 changed files with 72 additions and 4 deletions

View 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

View file

@ -552,8 +552,8 @@
<!--
# 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

View 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 {

View 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 {

View 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;

View 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);
}

View 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,

View 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;
}

View 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;