mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Enforce command policies
This commit is contained in:
		
							parent
							
								
									f23880b1fd
								
							
						
					
					
						commit
						39cf9a82f7
					
				
					 6 changed files with 39 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -54,7 +54,7 @@ int sp_index;
 | 
			
		|||
/**
 | 
			
		||||
 * Parse and handles a command.
 | 
			
		||||
 */
 | 
			
		||||
struct cmd_results *handle_command(char *command);
 | 
			
		||||
struct cmd_results *handle_command(char *command, enum command_context context);
 | 
			
		||||
/**
 | 
			
		||||
 * Parse and handles a command during config file loading.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,8 @@
 | 
			
		|||
enum secure_feature get_feature_policy(pid_t pid);
 | 
			
		||||
enum command_context get_command_policy(const char *cmd);
 | 
			
		||||
 | 
			
		||||
const char *command_policy_str(enum command_context context);
 | 
			
		||||
 | 
			
		||||
struct feature_policy *alloc_feature_policy(const char *program);
 | 
			
		||||
struct command_policy *alloc_command_policy(const char *command);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -323,7 +323,7 @@ static struct cmd_handler *find_handler(char *line, enum cmd_status block) {
 | 
			
		|||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct cmd_results *handle_command(char *_exec) {
 | 
			
		||||
struct cmd_results *handle_command(char *_exec, enum command_context context) {
 | 
			
		||||
	// Even though this function will process multiple commands we will only
 | 
			
		||||
	// return the last error, if any (for now). (Since we have access to an
 | 
			
		||||
	// error string we could e.g. concatonate all errors there.)
 | 
			
		||||
| 
						 | 
				
			
			@ -397,6 +397,16 @@ struct cmd_results *handle_command(char *_exec) {
 | 
			
		|||
				free_argv(argc, argv);
 | 
			
		||||
				goto cleanup;
 | 
			
		||||
			}
 | 
			
		||||
			if (!(get_command_policy(argv[0]) & context)) {
 | 
			
		||||
				if (results) {
 | 
			
		||||
					free_cmd_results(results);
 | 
			
		||||
				}
 | 
			
		||||
				results = cmd_results_new(CMD_INVALID, cmd,
 | 
			
		||||
						"Permission denied for %s via %s", cmd,
 | 
			
		||||
						command_policy_str(context));
 | 
			
		||||
				free_argv(argc, argv);
 | 
			
		||||
				goto cleanup;
 | 
			
		||||
			}
 | 
			
		||||
			struct cmd_results *res = handler->handle(argc-1, argv+1);
 | 
			
		||||
			if (res->status != CMD_SUCCESS) {
 | 
			
		||||
				free_argv(argc, argv);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -386,7 +386,7 @@ static bool handle_view_created(wlc_handle handle) {
 | 
			
		|||
			struct criteria *crit = criteria->items[i];
 | 
			
		||||
			sway_log(L_DEBUG, "for_window '%s' matches new view %p, cmd: '%s'",
 | 
			
		||||
					crit->crit_raw, newview, crit->cmdlist);
 | 
			
		||||
			struct cmd_results *res = handle_command(crit->cmdlist);
 | 
			
		||||
			struct cmd_results *res = handle_command(crit->cmdlist, CONTEXT_CRITERIA);
 | 
			
		||||
			if (res->status != CMD_SUCCESS) {
 | 
			
		||||
				sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -585,7 +585,7 @@ static void handle_binding_command(struct sway_binding *binding) {
 | 
			
		|||
		reload = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct cmd_results *res = handle_command(binding->command);
 | 
			
		||||
	struct cmd_results *res = handle_command(binding->command, CONTEXT_BINDING);
 | 
			
		||||
	if (res->status != CMD_SUCCESS) {
 | 
			
		||||
		sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -936,18 +936,18 @@ bool handle_pointer_scroll(wlc_handle view, uint32_t time, const struct wlc_modi
 | 
			
		|||
		int y_amount = (int)_amount[1];
 | 
			
		||||
 | 
			
		||||
		if (x_amount > 0 && strcmp(config->floating_scroll_up_cmd, "")) {
 | 
			
		||||
			handle_command(config->floating_scroll_up_cmd);
 | 
			
		||||
			handle_command(config->floating_scroll_up_cmd, CONTEXT_BINDING);
 | 
			
		||||
			return EVENT_HANDLED;
 | 
			
		||||
		} else if (x_amount < 0 && strcmp(config->floating_scroll_down_cmd, "")) {
 | 
			
		||||
			handle_command(config->floating_scroll_down_cmd);
 | 
			
		||||
			handle_command(config->floating_scroll_down_cmd, CONTEXT_BINDING);
 | 
			
		||||
			return EVENT_HANDLED;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (y_amount > 0 && strcmp(config->floating_scroll_right_cmd, "")) {
 | 
			
		||||
			handle_command(config->floating_scroll_right_cmd);
 | 
			
		||||
			handle_command(config->floating_scroll_right_cmd, CONTEXT_BINDING);
 | 
			
		||||
			return EVENT_HANDLED;
 | 
			
		||||
		} else if (y_amount < 0 && strcmp(config->floating_scroll_left_cmd, "")) {
 | 
			
		||||
			handle_command(config->floating_scroll_left_cmd);
 | 
			
		||||
			handle_command(config->floating_scroll_left_cmd, CONTEXT_BINDING);
 | 
			
		||||
			return EVENT_HANDLED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -960,7 +960,7 @@ static void handle_wlc_ready(void) {
 | 
			
		|||
	config->active = true;
 | 
			
		||||
	while (config->cmd_queue->length) {
 | 
			
		||||
		char *line = config->cmd_queue->items[0];
 | 
			
		||||
		struct cmd_results *res = handle_command(line);
 | 
			
		||||
		struct cmd_results *res = handle_command(line, CONTEXT_CONFIG);
 | 
			
		||||
		if (res->status != CMD_SUCCESS) {
 | 
			
		||||
			sway_log(L_ERROR, "Error on line '%s': %s", line, res->error);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -312,7 +312,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
 | 
			
		|||
	switch (client->current_command) {
 | 
			
		||||
	case IPC_COMMAND:
 | 
			
		||||
	{
 | 
			
		||||
		struct cmd_results *results = handle_command(buf);
 | 
			
		||||
		struct cmd_results *results = handle_command(buf, CONTEXT_IPC);
 | 
			
		||||
		const char *json = cmd_results_to_json(results);
 | 
			
		||||
		char reply[256];
 | 
			
		||||
		int length = snprintf(reply, sizeof(reply), "%s", json);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,3 +64,20 @@ enum command_context get_command_policy(const char *cmd) {
 | 
			
		|||
 | 
			
		||||
	return default_policy;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *command_policy_str(enum command_context context) {
 | 
			
		||||
	switch (context) {
 | 
			
		||||
		case CONTEXT_ALL:
 | 
			
		||||
			return "all";
 | 
			
		||||
		case CONTEXT_CONFIG:
 | 
			
		||||
			return "config";
 | 
			
		||||
		case CONTEXT_BINDING:
 | 
			
		||||
			return "binding";
 | 
			
		||||
		case CONTEXT_IPC:
 | 
			
		||||
			return "IPC";
 | 
			
		||||
		case CONTEXT_CRITERIA:
 | 
			
		||||
			return "criteria";
 | 
			
		||||
		default:
 | 
			
		||||
			return "unknown";
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue