mirror of
https://github.com/swaywm/sway.git
synced 2026-04-29 06:46:22 -04:00
Flesh out security-related data structures
This commit is contained in:
parent
bce7068b65
commit
633cafb0d5
5 changed files with 25 additions and 172 deletions
|
|
@ -262,61 +262,21 @@ enum sway_popup_during_fullscreen {
|
||||||
POPUP_LEAVE,
|
POPUP_LEAVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum command_context {
|
|
||||||
CONTEXT_CONFIG = 1,
|
|
||||||
CONTEXT_BINDING = 2,
|
|
||||||
CONTEXT_IPC = 4,
|
|
||||||
CONTEXT_CRITERIA = 8,
|
|
||||||
CONTEXT_ALL = 0xFFFFFFFF,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct command_policy {
|
|
||||||
char *command;
|
|
||||||
uint32_t context;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum secure_feature {
|
enum secure_feature {
|
||||||
FEATURE_LOCK = 1,
|
FEATURE_FULLSCREEN = 1 << 0,
|
||||||
FEATURE_PANEL = 2,
|
FEATURE_DATA_CONTROL_MGR = 1 << 1,
|
||||||
FEATURE_BACKGROUND = 4,
|
FEATURE_DMABUF_EXPORT = 1 << 2,
|
||||||
FEATURE_SCREENSHOT = 8,
|
FEATURE_SCREENCOPY = 1 << 3,
|
||||||
FEATURE_FULLSCREEN = 16,
|
FEATURE_GAMMA_CONTROL = 1 << 4,
|
||||||
FEATURE_KEYBOARD = 32,
|
FEATURE_INPUT_INHIBIT = 1 << 5,
|
||||||
FEATURE_MOUSE = 64,
|
FEATURE_LAYER_SHELL = 1 << 6,
|
||||||
|
FEATURE_VIRTUAL_KEYBOARD = 1 << 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct feature_policy {
|
struct feature_policy {
|
||||||
char *program;
|
char *program;
|
||||||
uint32_t features;
|
uint64_t permit_features;
|
||||||
};
|
uint64_t reject_features;
|
||||||
|
|
||||||
enum ipc_feature {
|
|
||||||
IPC_FEATURE_COMMAND = 1,
|
|
||||||
IPC_FEATURE_GET_WORKSPACES = 2,
|
|
||||||
IPC_FEATURE_GET_OUTPUTS = 4,
|
|
||||||
IPC_FEATURE_GET_TREE = 8,
|
|
||||||
IPC_FEATURE_GET_MARKS = 16,
|
|
||||||
IPC_FEATURE_GET_BAR_CONFIG = 32,
|
|
||||||
IPC_FEATURE_GET_VERSION = 64,
|
|
||||||
IPC_FEATURE_GET_INPUTS = 128,
|
|
||||||
IPC_FEATURE_EVENT_WORKSPACE = 256,
|
|
||||||
IPC_FEATURE_EVENT_OUTPUT = 512,
|
|
||||||
IPC_FEATURE_EVENT_MODE = 1024,
|
|
||||||
IPC_FEATURE_EVENT_WINDOW = 2048,
|
|
||||||
IPC_FEATURE_EVENT_BINDING = 4096,
|
|
||||||
IPC_FEATURE_EVENT_INPUT = 8192,
|
|
||||||
IPC_FEATURE_GET_SEATS = 16384,
|
|
||||||
|
|
||||||
IPC_FEATURE_ALL_COMMANDS =
|
|
||||||
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384,
|
|
||||||
IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192,
|
|
||||||
|
|
||||||
IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ipc_policy {
|
|
||||||
char *program;
|
|
||||||
uint32_t features;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum focus_wrapping_mode {
|
enum focus_wrapping_mode {
|
||||||
|
|
@ -410,9 +370,7 @@ struct sway_config {
|
||||||
int32_t floating_minimum_height;
|
int32_t floating_minimum_height;
|
||||||
|
|
||||||
// Security
|
// Security
|
||||||
list_t *command_policies;
|
|
||||||
list_t *feature_policies;
|
list_t *feature_policies;
|
||||||
list_t *ipc_policies;
|
|
||||||
|
|
||||||
// Context for command handlers
|
// Context for command handlers
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,17 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
|
|
||||||
uint32_t get_feature_policy_mask(pid_t pid);
|
/** Returns a mask of all features this pid is permitted to use */
|
||||||
uint32_t get_ipc_policy_mask(pid_t pid);
|
uint64_t get_feature_policy_mask(struct wl_client *client);
|
||||||
uint32_t get_command_policy_mask(const char *cmd);
|
|
||||||
|
|
||||||
struct feature_policy *get_feature_policy(const char *name);
|
/**
|
||||||
|
* Returns the feature policy for a given program. Creates one if it doesn't
|
||||||
|
* exist.
|
||||||
|
*/
|
||||||
|
struct feature_policy *get_feature_policy(const char *program);
|
||||||
|
|
||||||
const char *command_policy_str(enum command_context context);
|
/** Creates a wayland client with a feature policy applied. */
|
||||||
|
struct wl_client *create_secure_client(struct wl_display *display,
|
||||||
struct feature_policy *alloc_feature_policy(const char *program);
|
int fd, const struct feature_policy *policy);
|
||||||
struct ipc_policy *alloc_ipc_policy(const char *program);
|
|
||||||
struct command_policy *alloc_command_policy(const char *command);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -436,86 +436,6 @@ struct cmd_results *config_subcommand(char **argv, int argc,
|
||||||
"This command is shimmed, but unimplemented");
|
"This command is shimmed, but unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmd_results *config_commands_command(char *exec) {
|
|
||||||
struct cmd_results *results = NULL;
|
|
||||||
int argc;
|
|
||||||
char **argv = split_args(exec, &argc);
|
|
||||||
if (!argc) {
|
|
||||||
results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find handler for the command this is setting a policy for
|
|
||||||
char *cmd = argv[0];
|
|
||||||
|
|
||||||
if (strcmp(cmd, "}") == 0) {
|
|
||||||
results = cmd_results_new(CMD_BLOCK_END, NULL, NULL);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cmd_handler *handler = find_handler(cmd, NULL, 0);
|
|
||||||
if (!handler && strcmp(cmd, "*") != 0) {
|
|
||||||
results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum command_context context = 0;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
char *name;
|
|
||||||
enum command_context context;
|
|
||||||
} context_names[] = {
|
|
||||||
{ "config", CONTEXT_CONFIG },
|
|
||||||
{ "binding", CONTEXT_BINDING },
|
|
||||||
{ "ipc", CONTEXT_IPC },
|
|
||||||
{ "criteria", CONTEXT_CRITERIA },
|
|
||||||
{ "all", CONTEXT_ALL },
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
|
||||||
size_t j;
|
|
||||||
for (j = 0; j < sizeof(context_names) / sizeof(context_names[0]); ++j) {
|
|
||||||
if (strcmp(context_names[j].name, argv[i]) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (j == sizeof(context_names) / sizeof(context_names[0])) {
|
|
||||||
results = cmd_results_new(CMD_INVALID, cmd,
|
|
||||||
"Invalid command context %s", argv[i]);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
context |= context_names[j].context;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct command_policy *policy = NULL;
|
|
||||||
for (int i = 0; i < config->command_policies->length; ++i) {
|
|
||||||
struct command_policy *p = config->command_policies->items[i];
|
|
||||||
if (strcmp(p->command, cmd) == 0) {
|
|
||||||
policy = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!policy) {
|
|
||||||
policy = alloc_command_policy(cmd);
|
|
||||||
if (!sway_assert(policy, "Unable to allocate security policy")) {
|
|
||||||
results = cmd_results_new(CMD_INVALID, cmd,
|
|
||||||
"Unable to allocate memory");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
list_add(config->command_policies, policy);
|
|
||||||
}
|
|
||||||
policy->context = context;
|
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "Set command policy for %s to %d",
|
|
||||||
policy->command, policy->context);
|
|
||||||
|
|
||||||
results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
free_argv(argc, argv);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cmd_results *cmd_results_new(enum cmd_status status,
|
struct cmd_results *cmd_results_new(enum cmd_status status,
|
||||||
const char *input, const char *format, ...) {
|
const char *input, const char *format, ...) {
|
||||||
struct cmd_results *results = malloc(sizeof(struct cmd_results));
|
struct cmd_results *results = malloc(sizeof(struct cmd_results));
|
||||||
|
|
|
||||||
|
|
@ -128,9 +128,8 @@ void free_config(struct sway_config *config) {
|
||||||
list_free(config->no_focus);
|
list_free(config->no_focus);
|
||||||
list_free(config->active_bar_modifiers);
|
list_free(config->active_bar_modifiers);
|
||||||
list_free(config->config_chain);
|
list_free(config->config_chain);
|
||||||
list_free(config->command_policies);
|
// TODO: Deallocate feature policies
|
||||||
list_free(config->feature_policies);
|
list_free(config->feature_policies);
|
||||||
list_free(config->ipc_policies);
|
|
||||||
free(config->floating_scroll_up_cmd);
|
free(config->floating_scroll_up_cmd);
|
||||||
free(config->floating_scroll_down_cmd);
|
free(config->floating_scroll_down_cmd);
|
||||||
free(config->floating_scroll_left_cmd);
|
free(config->floating_scroll_left_cmd);
|
||||||
|
|
@ -291,10 +290,7 @@ static void config_defaults(struct sway_config *config) {
|
||||||
|
|
||||||
set_color(config->border_colors.background, 0xFFFFFF);
|
set_color(config->border_colors.background, 0xFFFFFF);
|
||||||
|
|
||||||
// Security
|
|
||||||
if (!(config->command_policies = create_list())) goto cleanup;
|
|
||||||
if (!(config->feature_policies = create_list())) goto cleanup;
|
if (!(config->feature_policies = create_list())) goto cleanup;
|
||||||
if (!(config->ipc_policies = create_list())) goto cleanup;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
@ -453,7 +449,8 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
|
||||||
"and mode 644 or 444", _path);
|
"and mode 644 or 444", _path);
|
||||||
success = false;
|
success = false;
|
||||||
} else {
|
} else {
|
||||||
success = success && load_config(_path, config);
|
success = success && load_config(_path, config,
|
||||||
|
&config->swaynag_config_errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -713,13 +710,7 @@ bool read_config(FILE *file, struct sway_config *config,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
wlr_log(WLR_DEBUG, "Expanded line: %s", expanded);
|
wlr_log(WLR_DEBUG, "Expanded line: %s", expanded);
|
||||||
struct cmd_results *res;
|
struct cmd_results *res = config_command(expanded);
|
||||||
if (block && strcmp(block, "<commands>") == 0) {
|
|
||||||
// Special case
|
|
||||||
res = config_commands_command(expanded);
|
|
||||||
} else {
|
|
||||||
res = config_command(expanded);
|
|
||||||
}
|
|
||||||
switch(res->status) {
|
switch(res->status) {
|
||||||
case CMD_FAILURE:
|
case CMD_FAILURE:
|
||||||
case CMD_INVALID:
|
case CMD_INVALID:
|
||||||
|
|
@ -738,11 +729,6 @@ bool read_config(FILE *file, struct sway_config *config,
|
||||||
list_add(config->cmd_queue, strdup(expanded));
|
list_add(config->cmd_queue, strdup(expanded));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_BLOCK_COMMANDS:
|
|
||||||
wlr_log(WLR_DEBUG, "Entering commands block");
|
|
||||||
list_insert(stack, 0, "<commands>");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CMD_BLOCK:
|
case CMD_BLOCK:
|
||||||
wlr_log(WLR_DEBUG, "Entering block '%s'", res->input);
|
wlr_log(WLR_DEBUG, "Entering block '%s'", res->input);
|
||||||
list_insert(stack, 0, strdup(res->input));
|
list_insert(stack, 0, strdup(res->input));
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,4 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "sway/security.h"
|
#include "sway/security.h"
|
||||||
|
|
||||||
struct command_policy *alloc_command_policy(const char *command) {
|
// TODO
|
||||||
struct command_policy *policy = malloc(sizeof(struct command_policy));
|
|
||||||
if (!policy) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
policy->command = strdup(command);
|
|
||||||
if (!policy->command) {
|
|
||||||
free(policy);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
policy->context = 0;
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue