Add ipc connection feature policy controls
This commit is contained in:
parent
62dad7148f
commit
d353da248b
|
@ -202,6 +202,7 @@ enum secure_feature {
|
||||||
FEATURE_FULLSCREEN = 16,
|
FEATURE_FULLSCREEN = 16,
|
||||||
FEATURE_KEYBOARD = 32,
|
FEATURE_KEYBOARD = 32,
|
||||||
FEATURE_MOUSE = 64,
|
FEATURE_MOUSE = 64,
|
||||||
|
FEATURE_IPC = 128,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct feature_policy {
|
struct feature_policy {
|
||||||
|
|
|
@ -542,16 +542,15 @@ struct cmd_results *config_commands_command(char *exec) {
|
||||||
{ "criteria", CONTEXT_CRITERIA },
|
{ "criteria", CONTEXT_CRITERIA },
|
||||||
{ "all", CONTEXT_ALL },
|
{ "all", CONTEXT_ALL },
|
||||||
};
|
};
|
||||||
size_t names_len = 5;
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
size_t j;
|
size_t j;
|
||||||
for (j = 0; j < names_len; ++j) {
|
for (j = 0; j < sizeof(context_names) / sizeof(context_names[0]); ++j) {
|
||||||
if (strcmp(context_names[j].name, argv[i]) == 0) {
|
if (strcmp(context_names[j].name, argv[i]) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j == names_len) {
|
if (j == sizeof(context_names) / sizeof(context_names[0])) {
|
||||||
results = cmd_results_new(CMD_INVALID, cmd,
|
results = cmd_results_new(CMD_INVALID, cmd,
|
||||||
"Invalid command context %s", argv[i]);
|
"Invalid command context %s", argv[i]);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
@ -19,17 +19,17 @@ static enum secure_feature get_features(int argc, char **argv,
|
||||||
{ "fullscreen", FEATURE_FULLSCREEN },
|
{ "fullscreen", FEATURE_FULLSCREEN },
|
||||||
{ "keyboard", FEATURE_KEYBOARD },
|
{ "keyboard", FEATURE_KEYBOARD },
|
||||||
{ "mouse", FEATURE_MOUSE },
|
{ "mouse", FEATURE_MOUSE },
|
||||||
|
{ "ipc", FEATURE_IPC },
|
||||||
};
|
};
|
||||||
size_t names_len = 7;
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
size_t j;
|
size_t j;
|
||||||
for (j = 0; j < names_len; ++j) {
|
for (j = 0; j < sizeof(feature_names) / sizeof(feature_names[0]); ++j) {
|
||||||
if (strcmp(feature_names[j].name, argv[i]) == 0) {
|
if (strcmp(feature_names[j].name, argv[i]) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j == names_len) {
|
if (j == sizeof(feature_names) / sizeof(feature_names[0])) {
|
||||||
*error = cmd_results_new(CMD_INVALID,
|
*error = cmd_results_new(CMD_INVALID,
|
||||||
"permit", "Invalid feature grant %s", argv[i]);
|
"permit", "Invalid feature grant %s", argv[i]);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <libinput.h>
|
#include <libinput.h>
|
||||||
#include "sway/ipc-json.h"
|
#include "sway/ipc-json.h"
|
||||||
#include "sway/ipc-server.h"
|
#include "sway/ipc-server.h"
|
||||||
|
#include "sway/security.h"
|
||||||
#include "sway/config.h"
|
#include "sway/config.h"
|
||||||
#include "sway/commands.h"
|
#include "sway/commands.h"
|
||||||
#include "sway/input.h"
|
#include "sway/input.h"
|
||||||
|
@ -124,6 +125,17 @@ struct sockaddr_un *ipc_user_sockaddr(void) {
|
||||||
return ipc_sockaddr;
|
return ipc_sockaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pid_t get_client_pid(int client_fd) {
|
||||||
|
struct ucred ucred;
|
||||||
|
socklen_t len = sizeof(struct ucred);
|
||||||
|
|
||||||
|
if (getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ucred.pid;
|
||||||
|
}
|
||||||
|
|
||||||
int ipc_handle_connection(int fd, uint32_t mask, void *data) {
|
int ipc_handle_connection(int fd, uint32_t mask, void *data) {
|
||||||
(void) fd; (void) data;
|
(void) fd; (void) data;
|
||||||
sway_log(L_DEBUG, "Event on IPC listening socket");
|
sway_log(L_DEBUG, "Event on IPC listening socket");
|
||||||
|
@ -142,6 +154,15 @@ int ipc_handle_connection(int fd, uint32_t mask, void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t pid = get_client_pid(client_fd);
|
||||||
|
if (!(get_feature_policy(pid) & FEATURE_IPC)) {
|
||||||
|
sway_log(L_INFO, "Permission to connect to IPC socket denied to %d", pid);
|
||||||
|
const char *error = "{\"success\": false, \"message\": \"Permission denied\"}";
|
||||||
|
write(client_fd, &error, sizeof(error));
|
||||||
|
close(client_fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct ipc_client* client = malloc(sizeof(struct ipc_client));
|
struct ipc_client* client = malloc(sizeof(struct ipc_client));
|
||||||
client->payload_length = 0;
|
client->payload_length = 0;
|
||||||
client->fd = client_fd;
|
client->fd = client_fd;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
struct feature_policy *alloc_feature_policy(const char *program) {
|
struct feature_policy *alloc_feature_policy(const char *program) {
|
||||||
struct feature_policy *policy = malloc(sizeof(struct feature_policy));
|
struct feature_policy *policy = malloc(sizeof(struct feature_policy));
|
||||||
policy->program = strdup(program);
|
policy->program = strdup(program);
|
||||||
policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE;
|
policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE | FEATURE_IPC;
|
||||||
return policy;
|
return policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,9 @@ policies. These features are:
|
||||||
Permission to become fullscreen. Note that users can always make a window
|
Permission to become fullscreen. Note that users can always make a window
|
||||||
fullscreen themselves with the fullscreen command.
|
fullscreen themselves with the fullscreen command.
|
||||||
|
|
||||||
|
**ipc**::
|
||||||
|
Permission to connect to sway's IPC socket.
|
||||||
|
|
||||||
**keyboard**::
|
**keyboard**::
|
||||||
Permission to receive keyboard events (only while they are focused).
|
Permission to receive keyboard events (only while they are focused).
|
||||||
|
|
||||||
|
@ -98,9 +101,9 @@ policies. These features are:
|
||||||
**screenshot**::
|
**screenshot**::
|
||||||
Permission to take screenshots or record the screen.
|
Permission to take screenshots or record the screen.
|
||||||
|
|
||||||
By default, all programs are granted **fullscreen**, **keyboard**, and **mouse**
|
By default, all programs are granted **fullscreen**, **keyboard**, **mouse**, and
|
||||||
permissions. You can use the following config commands to control a program's
|
**ipc** permissions. You can use the following config commands to control a
|
||||||
access:
|
program's access:
|
||||||
|
|
||||||
**permit** <executable> <features...>::
|
**permit** <executable> <features...>::
|
||||||
Permits <executable> to use <features> (each feature seperated by a space).
|
Permits <executable> to use <features> (each feature seperated by a space).
|
||||||
|
|
Loading…
Reference in a new issue