Implement permit and reject commands

This commit is contained in:
Drew DeVault 2016-12-01 21:36:43 -05:00
parent 1a8a42f372
commit 76cab04b4d
8 changed files with 115 additions and 22 deletions

View file

@ -6,10 +6,10 @@
# installation. # installation.
# Configures which programs are allowed to use which sway features # Configures which programs are allowed to use which sway features
permit $PREFIX/swaylock lock permit __PREFIX__/swaylock lock
permit $PREFIX/swaybar panel permit __PREFIX__/swaybar panel
permit $PREFIX/swaybg background permit __PREFIX__/swaybg background
permit $PREFIX/swaygrab screenshot permit __PREFIX__/swaygrab screenshot
permit * fullscreen keyboard mouse permit * fullscreen keyboard mouse

View file

@ -195,10 +195,4 @@ bar {
} }
} }
# You may want this: include __SYSCONFDIR__/etc/sway/config.d/*
#
# include ~/.config/sway/conf.d/*
#
# Protip:
#
# include ~/.config/sway/`hostname`/*

View file

@ -1,9 +0,0 @@
#ifndef _SWAY_SECURITY_H
#define _SWAY_SECURITY_H
#include <unistd.h>
#include "sway/config.h"
enum secure_features get_feature_policy(pid_t pid);
enum command_context get_command_policy(const char *cmd);
#endif

View file

@ -122,6 +122,8 @@ sway_cmd cmd_new_float;
sway_cmd cmd_new_window; sway_cmd cmd_new_window;
sway_cmd cmd_orientation; sway_cmd cmd_orientation;
sway_cmd cmd_output; sway_cmd cmd_output;
sway_cmd cmd_permit;
sway_cmd cmd_reject;
sway_cmd cmd_reload; sway_cmd cmd_reload;
sway_cmd cmd_resize; sway_cmd cmd_resize;
sway_cmd cmd_scratchpad; sway_cmd cmd_scratchpad;

View file

@ -3,7 +3,9 @@
#include <unistd.h> #include <unistd.h>
#include "sway/config.h" #include "sway/config.h"
const struct feature_permissions *get_permissions(pid_t pid); enum secure_feature get_feature_policy(pid_t pid);
enum command_context get_command_context(const char *cmd); enum command_context get_command_policy(const char *cmd);
struct feature_policy *alloc_feature_policy(const char *program);
#endif #endif

View file

@ -187,6 +187,8 @@ static struct cmd_handler handlers[] = {
{ "new_float", cmd_new_float }, { "new_float", cmd_new_float },
{ "new_window", cmd_new_window }, { "new_window", cmd_new_window },
{ "output", cmd_output }, { "output", cmd_output },
{ "permit", cmd_permit },
{ "reject", cmd_reject },
{ "reload", cmd_reload }, { "reload", cmd_reload },
{ "resize", cmd_resize }, { "resize", cmd_resize },
{ "scratchpad", cmd_scratchpad }, { "scratchpad", cmd_scratchpad },

95
sway/commands/permit.c Normal file
View file

@ -0,0 +1,95 @@
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
#include "sway/security.h"
#include "log.h"
static enum secure_feature get_features(int argc, char **argv,
struct cmd_results **error) {
enum secure_feature features = 0;
struct {
char *name;
enum secure_feature feature;
} feature_names[] = {
{ "lock", FEATURE_LOCK },
{ "panel", FEATURE_PANEL },
{ "background", FEATURE_BACKGROUND },
{ "screenshot", FEATURE_SCREENSHOT },
{ "fullscreen", FEATURE_FULLSCREEN },
{ "keyboard", FEATURE_KEYBOARD },
{ "mouse", FEATURE_MOUSE },
};
size_t names_len = sizeof(feature_names) /
(sizeof(char *) + sizeof(enum secure_feature));
for (int i = 1; i < argc; ++i) {
size_t j;
for (j = 0; j < names_len; ++j) {
if (strcmp(feature_names[j].name, argv[i]) == 0) {
break;
}
}
if (j == names_len) {
*error = cmd_results_new(CMD_INVALID,
"permit", "Invalid feature grant %s", argv[i]);
return 0;
}
features |= feature_names[j].feature;
}
return features;
}
static struct feature_policy *get_policy(const char *name) {
struct feature_policy *policy = NULL;
for (int i = 0; i < config->feature_policies->length; ++i) {
struct feature_policy *p = config->feature_policies->items[i];
if (strcmp(p->program, name) == 0) {
policy = p;
break;
}
}
if (!policy) {
policy = alloc_feature_policy(name);
list_add(config->feature_policies, policy);
}
return policy;
}
struct cmd_results *cmd_permit(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "permit", EXPECTED_MORE_THAN, 1))) {
return error;
}
struct feature_policy *policy = get_policy(argv[0]);
policy->features |= get_features(argc, argv, &error);
if (error) {
return error;
}
sway_log(L_DEBUG, "Permissions granted to %s for features %d",
policy->program, policy->features);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
struct cmd_results *cmd_reject(int argc, char **argv) {
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "reject", EXPECTED_MORE_THAN, 1))) {
return error;
}
struct feature_policy *policy = get_policy(argv[0]);
policy->features &= ~get_features(argc, argv, &error);
if (error) {
return error;
}
sway_log(L_DEBUG, "Permissions granted to %s for features %d",
policy->program, policy->features);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}

View file

@ -4,6 +4,13 @@
#include "sway/security.h" #include "sway/security.h"
#include "log.h" #include "log.h"
struct feature_policy *alloc_feature_policy(const char *program) {
struct feature_policy *policy = malloc(sizeof(struct feature_policy));
policy->program = strdup(program);
policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE;
return policy;
}
enum secure_feature get_feature_policy(pid_t pid) { enum secure_feature get_feature_policy(pid_t pid) {
const char *fmt = "/proc/%d/exe"; const char *fmt = "/proc/%d/exe";
int pathlen = snprintf(NULL, 0, fmt, pid); int pathlen = snprintf(NULL, 0, fmt, pid);