mirror of
https://github.com/swaywm/sway.git
synced 2026-04-30 06:46:24 -04:00
Merge 6833c898bf into 5ed533a943
This commit is contained in:
commit
28f3790207
5 changed files with 52 additions and 45 deletions
|
|
@ -208,6 +208,7 @@ enum secure_feature {
|
||||||
struct feature_policy {
|
struct feature_policy {
|
||||||
char *program;
|
char *program;
|
||||||
uint32_t features;
|
uint32_t features;
|
||||||
|
bool validated;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ipc_feature {
|
enum ipc_feature {
|
||||||
|
|
@ -235,6 +236,7 @@ enum ipc_feature {
|
||||||
struct ipc_policy {
|
struct ipc_policy {
|
||||||
char *program;
|
char *program;
|
||||||
uint32_t features;
|
uint32_t features;
|
||||||
|
bool validated;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,5 @@ struct feature_policy *alloc_feature_policy(const char *program);
|
||||||
struct ipc_policy *alloc_ipc_policy(const char *program);
|
struct ipc_policy *alloc_ipc_policy(const char *program);
|
||||||
struct command_policy *alloc_command_policy(const char *command);
|
struct command_policy *alloc_command_policy(const char *command);
|
||||||
|
|
||||||
|
char *resolve_ipc_path(const char* program);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,26 +18,26 @@ struct cmd_results *cmd_ipc(int argc, char **argv) {
|
||||||
if ((error = check_security_config())) {
|
if ((error = check_security_config())) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *program = NULL;
|
|
||||||
|
|
||||||
if (!strcmp(argv[0], "*")) {
|
|
||||||
program = strdup(argv[0]);
|
|
||||||
} else if (!(program = resolve_path(argv[0]))) {
|
|
||||||
return cmd_results_new(
|
|
||||||
CMD_INVALID, "ipc", "Unable to resolve IPC Policy target.");
|
|
||||||
}
|
|
||||||
if (config->reading && strcmp("{", argv[1]) != 0) {
|
if (config->reading && strcmp("{", argv[1]) != 0) {
|
||||||
return cmd_results_new(CMD_INVALID, "ipc",
|
return cmd_results_new(CMD_INVALID, "ipc",
|
||||||
"Expected '{' at start of IPC config definition.");
|
"Expected '{' at start of IPC config definition.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config->reading) {
|
if (!config->reading) {
|
||||||
return cmd_results_new(CMD_FAILURE, "ipc", "Can only be used in config file.");
|
return cmd_results_new(CMD_FAILURE, "ipc", "Can only be used in config file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
current_policy = alloc_ipc_policy(program);
|
char *program = NULL;
|
||||||
list_add(config->ipc_policies, current_policy);
|
|
||||||
|
if (!(program = resolve_ipc_path(argv[0]))) {
|
||||||
|
return cmd_results_new(
|
||||||
|
CMD_FAILURE, "ipc", "Memory allocation error occured.");
|
||||||
|
}
|
||||||
|
if ((current_policy = alloc_ipc_policy(program))) {
|
||||||
|
list_add(config->ipc_policies, current_policy);
|
||||||
|
} else {
|
||||||
|
return cmd_results_new(
|
||||||
|
CMD_FAILURE, "ipc", "Failed to allocate security policy.");
|
||||||
|
}
|
||||||
|
|
||||||
free(program);
|
free(program);
|
||||||
return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL);
|
return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL);
|
||||||
|
|
|
||||||
|
|
@ -49,27 +49,20 @@ struct cmd_results *cmd_permit(int argc, char **argv) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool assign_perms = true;
|
|
||||||
char *program = NULL;
|
char *program = NULL;
|
||||||
|
if (!(program = resolve_ipc_path(argv[0]))) {
|
||||||
if (!strcmp(argv[0], "*")) {
|
sway_abort("memory allocation failed");
|
||||||
program = strdup(argv[0]);
|
|
||||||
} else {
|
|
||||||
program = resolve_path(argv[0]);
|
|
||||||
}
|
|
||||||
if (!program) {
|
|
||||||
sway_assert(program, "Unable to resolve IPC permit target '%s'."
|
|
||||||
" will issue empty policy", argv[0]);
|
|
||||||
assign_perms = false;
|
|
||||||
program = strdup(argv[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct feature_policy *policy = get_feature_policy(program);
|
struct feature_policy *policy = get_feature_policy(program);
|
||||||
if (assign_perms) {
|
if (policy->validated) {
|
||||||
policy->features |= get_features(argc, argv, &error);
|
policy->features |= get_features(argc, argv, &error);
|
||||||
|
sway_log(L_DEBUG, "Permissions granted to %s for features %d",
|
||||||
|
policy->program, policy->features);
|
||||||
|
} else {
|
||||||
|
sway_log(L_ERROR, "Unable to validate IPC permit target '%s'."
|
||||||
|
" will issue empty policy", argv[0]);
|
||||||
}
|
}
|
||||||
sway_log(L_DEBUG, "Permissions granted to %s for features %d",
|
|
||||||
policy->program, policy->features);
|
|
||||||
|
|
||||||
free(program);
|
free(program);
|
||||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||||
|
|
@ -85,19 +78,15 @@ struct cmd_results *cmd_reject(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char *program = NULL;
|
char *program = NULL;
|
||||||
if (!strcmp(argv[0], "*")) {
|
if (!(program = resolve_ipc_path(argv[0]))) {
|
||||||
program = strdup(argv[0]);
|
sway_abort("memory allocation failed");
|
||||||
} else {
|
|
||||||
program = resolve_path(argv[0]);
|
|
||||||
}
|
|
||||||
if (!program) {
|
|
||||||
// Punt
|
|
||||||
sway_log(L_INFO, "Unable to resolve IPC reject target '%s'."
|
|
||||||
" Will use provided path", argv[0]);
|
|
||||||
program = strdup(argv[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct feature_policy *policy = get_feature_policy(program);
|
struct feature_policy *policy = get_feature_policy(program);
|
||||||
|
if (!policy->validated) {
|
||||||
|
sway_log(L_ERROR, "Unable to validate IPC reject target '%s'."
|
||||||
|
" Allowing `reject` directive anyway", argv[0]);
|
||||||
|
}
|
||||||
policy->features &= ~get_features(argc, argv, &error);
|
policy->features &= ~get_features(argc, argv, &error);
|
||||||
|
|
||||||
sway_log(L_DEBUG, "Permissions granted to %s for features %d",
|
sway_log(L_DEBUG, "Permissions granted to %s for features %d",
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/security.h"
|
#include "sway/security.h"
|
||||||
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
static bool validate_ipc_target(const char *program) {
|
static bool validate_ipc_target(const char *program) {
|
||||||
|
|
@ -21,7 +22,7 @@ static bool validate_ipc_target(const char *program) {
|
||||||
}
|
}
|
||||||
if (!S_ISREG(sb.st_mode)) {
|
if (!S_ISREG(sb.st_mode)) {
|
||||||
sway_log(L_ERROR,
|
sway_log(L_ERROR,
|
||||||
"IPC target '%s' MUST be/point at an existing regular file",
|
"IPC target '%s' MUST point at an existing file",
|
||||||
program);
|
program);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +31,7 @@ static bool validate_ipc_target(const char *program) {
|
||||||
sway_log(L_ERROR, "IPC target '%s' MUST be owned by root", program);
|
sway_log(L_ERROR, "IPC target '%s' MUST be owned by root", program);
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
sway_log(L_INFO, "IPC target '%s' MUST be owned by root (waived for debug build)", program);
|
sway_log(L_ERROR, "IPC target '%s' MUST be owned by root (waived for debug build)", program);
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -45,9 +46,6 @@ static bool validate_ipc_target(const char *program) {
|
||||||
struct feature_policy *alloc_feature_policy(const char *program) {
|
struct feature_policy *alloc_feature_policy(const char *program) {
|
||||||
uint32_t default_policy = 0;
|
uint32_t default_policy = 0;
|
||||||
|
|
||||||
if (!validate_ipc_target(program)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < config->feature_policies->length; ++i) {
|
for (int i = 0; i < config->feature_policies->length; ++i) {
|
||||||
struct feature_policy *policy = config->feature_policies->items[i];
|
struct feature_policy *policy = config->feature_policies->items[i];
|
||||||
if (strcmp(policy->program, "*") == 0) {
|
if (strcmp(policy->program, "*") == 0) {
|
||||||
|
|
@ -60,6 +58,7 @@ struct feature_policy *alloc_feature_policy(const char *program) {
|
||||||
if (!policy) {
|
if (!policy) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
policy->validated = validate_ipc_target (program);
|
||||||
policy->program = strdup(program);
|
policy->program = strdup(program);
|
||||||
if (!policy->program) {
|
if (!policy->program) {
|
||||||
free(policy);
|
free(policy);
|
||||||
|
|
@ -73,9 +72,6 @@ struct feature_policy *alloc_feature_policy(const char *program) {
|
||||||
struct ipc_policy *alloc_ipc_policy(const char *program) {
|
struct ipc_policy *alloc_ipc_policy(const char *program) {
|
||||||
uint32_t default_policy = 0;
|
uint32_t default_policy = 0;
|
||||||
|
|
||||||
if (!validate_ipc_target(program)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < config->ipc_policies->length; ++i) {
|
for (int i = 0; i < config->ipc_policies->length; ++i) {
|
||||||
struct ipc_policy *policy = config->ipc_policies->items[i];
|
struct ipc_policy *policy = config->ipc_policies->items[i];
|
||||||
if (strcmp(policy->program, "*") == 0) {
|
if (strcmp(policy->program, "*") == 0) {
|
||||||
|
|
@ -88,6 +84,7 @@ struct ipc_policy *alloc_ipc_policy(const char *program) {
|
||||||
if (!policy) {
|
if (!policy) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
policy->validated = validate_ipc_target (program);
|
||||||
policy->program = strdup(program);
|
policy->program = strdup(program);
|
||||||
if (!policy->program) {
|
if (!policy->program) {
|
||||||
free(policy);
|
free(policy);
|
||||||
|
|
@ -226,3 +223,21 @@ const char *command_policy_str(enum command_context context) {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IPC-specific version of util.c:resolve_path()
|
||||||
|
* Always returns the "best" path It can unless an ENOMEM occurs ,
|
||||||
|
* in which case it returns NULL.
|
||||||
|
*/
|
||||||
|
char *resolve_ipc_path(const char* name) {
|
||||||
|
char *program = NULL;
|
||||||
|
if (!strcmp(name, "*")) {
|
||||||
|
program = strdup(name);
|
||||||
|
} else {
|
||||||
|
program = resolve_path(name);
|
||||||
|
if (!program) {
|
||||||
|
program = strdup(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue