summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2016-12-02 18:08:15 -0500
committerLibravatar Drew DeVault <sir@cmpwn.com>2016-12-02 18:09:19 -0500
commitd353da248b4653d7bc027ff0dceca946cdd0b22f (patch)
treeb76f5d9b8164a9eb102eee6b6cb13c5b9f6cbc75
parentEnforce IPC security policy (diff)
downloadsway-d353da248b4653d7bc027ff0dceca946cdd0b22f.tar.gz
sway-d353da248b4653d7bc027ff0dceca946cdd0b22f.tar.zst
sway-d353da248b4653d7bc027ff0dceca946cdd0b22f.zip
Add ipc connection feature policy controls
-rw-r--r--include/sway/config.h1
-rw-r--r--sway/commands.c5
-rw-r--r--sway/commands/permit.c6
-rw-r--r--sway/ipc-server.c21
-rw-r--r--sway/security.c2
-rw-r--r--sway/sway-security.7.txt9
6 files changed, 34 insertions, 10 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 192e697c..2c6b83e7 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -202,6 +202,7 @@ enum secure_feature {
202 FEATURE_FULLSCREEN = 16, 202 FEATURE_FULLSCREEN = 16,
203 FEATURE_KEYBOARD = 32, 203 FEATURE_KEYBOARD = 32,
204 FEATURE_MOUSE = 64, 204 FEATURE_MOUSE = 64,
205 FEATURE_IPC = 128,
205}; 206};
206 207
207struct feature_policy { 208struct feature_policy {
diff --git a/sway/commands.c b/sway/commands.c
index 47f7533c..3d8f8c5b 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -542,16 +542,15 @@ struct cmd_results *config_commands_command(char *exec) {
542 { "criteria", CONTEXT_CRITERIA }, 542 { "criteria", CONTEXT_CRITERIA },
543 { "all", CONTEXT_ALL }, 543 { "all", CONTEXT_ALL },
544 }; 544 };
545 size_t names_len = 5;
546 545
547 for (int i = 1; i < argc; ++i) { 546 for (int i = 1; i < argc; ++i) {
548 size_t j; 547 size_t j;
549 for (j = 0; j < names_len; ++j) { 548 for (j = 0; j < sizeof(context_names) / sizeof(context_names[0]); ++j) {
550 if (strcmp(context_names[j].name, argv[i]) == 0) { 549 if (strcmp(context_names[j].name, argv[i]) == 0) {
551 break; 550 break;
552 } 551 }
553 } 552 }
554 if (j == names_len) { 553 if (j == sizeof(context_names) / sizeof(context_names[0])) {
555 results = cmd_results_new(CMD_INVALID, cmd, 554 results = cmd_results_new(CMD_INVALID, cmd,
556 "Invalid command context %s", argv[i]); 555 "Invalid command context %s", argv[i]);
557 goto cleanup; 556 goto cleanup;
diff --git a/sway/commands/permit.c b/sway/commands/permit.c
index 258ea5b2..7a25e4ce 100644
--- a/sway/commands/permit.c
+++ b/sway/commands/permit.c
@@ -19,17 +19,17 @@ static enum secure_feature get_features(int argc, char **argv,
19 { "fullscreen", FEATURE_FULLSCREEN }, 19 { "fullscreen", FEATURE_FULLSCREEN },
20 { "keyboard", FEATURE_KEYBOARD }, 20 { "keyboard", FEATURE_KEYBOARD },
21 { "mouse", FEATURE_MOUSE }, 21 { "mouse", FEATURE_MOUSE },
22 { "ipc", FEATURE_IPC },
22 }; 23 };
23 size_t names_len = 7;
24 24
25 for (int i = 1; i < argc; ++i) { 25 for (int i = 1; i < argc; ++i) {
26 size_t j; 26 size_t j;
27 for (j = 0; j < names_len; ++j) { 27 for (j = 0; j < sizeof(feature_names) / sizeof(feature_names[0]); ++j) {
28 if (strcmp(feature_names[j].name, argv[i]) == 0) { 28 if (strcmp(feature_names[j].name, argv[i]) == 0) {
29 break; 29 break;
30 } 30 }
31 } 31 }
32 if (j == names_len) { 32 if (j == sizeof(feature_names) / sizeof(feature_names[0])) {
33 *error = cmd_results_new(CMD_INVALID, 33 *error = cmd_results_new(CMD_INVALID,
34 "permit", "Invalid feature grant %s", argv[i]); 34 "permit", "Invalid feature grant %s", argv[i]);
35 return 0; 35 return 0;
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index 15791c5e..c04c465a 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -15,6 +15,7 @@
15#include <libinput.h> 15#include <libinput.h>
16#include "sway/ipc-json.h" 16#include "sway/ipc-json.h"
17#include "sway/ipc-server.h" 17#include "sway/ipc-server.h"
18#include "sway/security.h"
18#include "sway/config.h" 19#include "sway/config.h"
19#include "sway/commands.h" 20#include "sway/commands.h"
20#include "sway/input.h" 21#include "sway/input.h"
@@ -124,6 +125,17 @@ struct sockaddr_un *ipc_user_sockaddr(void) {
124 return ipc_sockaddr; 125 return ipc_sockaddr;
125} 126}
126 127
128static pid_t get_client_pid(int client_fd) {
129 struct ucred ucred;
130 socklen_t len = sizeof(struct ucred);
131
132 if (getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
133 return -1;
134 }
135
136 return ucred.pid;
137}
138
127int ipc_handle_connection(int fd, uint32_t mask, void *data) { 139int ipc_handle_connection(int fd, uint32_t mask, void *data) {
128 (void) fd; (void) data; 140 (void) fd; (void) data;
129 sway_log(L_DEBUG, "Event on IPC listening socket"); 141 sway_log(L_DEBUG, "Event on IPC listening socket");
@@ -142,6 +154,15 @@ int ipc_handle_connection(int fd, uint32_t mask, void *data) {
142 return 0; 154 return 0;
143 } 155 }
144 156
157 pid_t pid = get_client_pid(client_fd);
158 if (!(get_feature_policy(pid) & FEATURE_IPC)) {
159 sway_log(L_INFO, "Permission to connect to IPC socket denied to %d", pid);
160 const char *error = "{\"success\": false, \"message\": \"Permission denied\"}";
161 write(client_fd, &error, sizeof(error));
162 close(client_fd);
163 return 0;
164 }
165
145 struct ipc_client* client = malloc(sizeof(struct ipc_client)); 166 struct ipc_client* client = malloc(sizeof(struct ipc_client));
146 client->payload_length = 0; 167 client->payload_length = 0;
147 client->fd = client_fd; 168 client->fd = client_fd;
diff --git a/sway/security.c b/sway/security.c
index 2ccc30fd..0d510253 100644
--- a/sway/security.c
+++ b/sway/security.c
@@ -7,7 +7,7 @@
7struct feature_policy *alloc_feature_policy(const char *program) { 7struct feature_policy *alloc_feature_policy(const char *program) {
8 struct feature_policy *policy = malloc(sizeof(struct feature_policy)); 8 struct feature_policy *policy = malloc(sizeof(struct feature_policy));
9 policy->program = strdup(program); 9 policy->program = strdup(program);
10 policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; 10 policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE | FEATURE_IPC;
11 return policy; 11 return policy;
12} 12}
13 13
diff --git a/sway/sway-security.7.txt b/sway/sway-security.7.txt
index a4122c5c..53c7b876 100644
--- a/sway/sway-security.7.txt
+++ b/sway/sway-security.7.txt
@@ -81,6 +81,9 @@ policies. These features are:
81 Permission to become fullscreen. Note that users can always make a window 81 Permission to become fullscreen. Note that users can always make a window
82 fullscreen themselves with the fullscreen command. 82 fullscreen themselves with the fullscreen command.
83 83
84**ipc**::
85 Permission to connect to sway's IPC socket.
86
84**keyboard**:: 87**keyboard**::
85 Permission to receive keyboard events (only while they are focused). 88 Permission to receive keyboard events (only while they are focused).
86 89
@@ -98,9 +101,9 @@ policies. These features are:
98**screenshot**:: 101**screenshot**::
99 Permission to take screenshots or record the screen. 102 Permission to take screenshots or record the screen.
100 103
101By default, all programs are granted **fullscreen**, **keyboard**, and **mouse** 104By default, all programs are granted **fullscreen**, **keyboard**, **mouse**, and
102permissions. You can use the following config commands to control a program's 105**ipc** permissions. You can use the following config commands to control a
103access: 106program's access:
104 107
105**permit** <executable> <features...>:: 108**permit** <executable> <features...>::
106 Permits <executable> to use <features> (each feature seperated by a space). 109 Permits <executable> to use <features> (each feature seperated by a space).