diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-09-08 10:19:33 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-10-08 18:35:39 -0400 |
commit | 3fa2d545dea85e804cb3139f74c39a25873a6af0 (patch) | |
tree | 2f2fb8255756eebe48db112e62ddf54e1fc7371c | |
parent | Implement permit & reject (diff) | |
download | sway-security.tar.gz sway-security.tar.zst sway-security.zip |
Add create_secure_client and create_client_socketsecurity
-rw-r--r-- | include/sway/config.h | 2 | ||||
-rw-r--r-- | include/sway/security.h | 10 | ||||
-rw-r--r-- | sway/commands/exec_always.c | 4 | ||||
-rw-r--r-- | sway/security.c | 50 |
4 files changed, 56 insertions, 10 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index 0861712e..6347c85e 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -273,7 +273,7 @@ enum secure_feature { | |||
273 | }; | 273 | }; |
274 | 274 | ||
275 | struct feature_policy { | 275 | struct feature_policy { |
276 | char *program; | 276 | char *command; |
277 | uint64_t permit_features; | 277 | uint64_t permit_features; |
278 | uint64_t reject_features; | 278 | uint64_t reject_features; |
279 | }; | 279 | }; |
diff --git a/include/sway/security.h b/include/sway/security.h index d1867633..df2aadbe 100644 --- a/include/sway/security.h +++ b/include/sway/security.h | |||
@@ -6,13 +6,15 @@ | |||
6 | /** Returns a mask of all features this client is permitted to use */ | 6 | /** Returns a mask of all features this client is permitted to use */ |
7 | uint64_t get_feature_policy_mask(struct wl_client *client); | 7 | uint64_t get_feature_policy_mask(struct wl_client *client); |
8 | 8 | ||
9 | /** Returns the policy for a program, or creates one if it doesn't exist. */ | 9 | /** Returns the policy for a command, or creates one if it doesn't exist. */ |
10 | struct feature_policy *get_feature_policy( | 10 | struct feature_policy *get_feature_policy( |
11 | struct sway_config *config, const char *program); | 11 | struct sway_config *config, const char *command); |
12 | 12 | ||
13 | /** Creates a wayland client with a feature policy applied. */ | 13 | /** Creates a wayland client with the appropriate feature policy. */ |
14 | struct wl_client *create_secure_client(struct wl_display *display, | 14 | struct wl_client *create_secure_client(struct wl_display *display, |
15 | int fd, const struct feature_policy *policy); | 15 | int fd, const char *command); |
16 | |||
17 | bool create_client_socket(int sv[2]); | ||
16 | 18 | ||
17 | struct feature_name { | 19 | struct feature_name { |
18 | char *name; | 20 | char *name; |
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index de78dd83..da8ce480 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c | |||
@@ -1,4 +1,4 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <stdint.h> | 3 | #include <stdint.h> |
4 | #include <string.h> | 4 | #include <string.h> |
@@ -57,6 +57,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { | |||
57 | sigemptyset(&set); | 57 | sigemptyset(&set); |
58 | sigprocmask(SIG_SETMASK, &set, NULL); | 58 | sigprocmask(SIG_SETMASK, &set, NULL); |
59 | close(fd[0]); | 59 | close(fd[0]); |
60 | |||
60 | if ((child = fork()) == 0) { | 61 | if ((child = fork()) == 0) { |
61 | close(fd[1]); | 62 | close(fd[1]); |
62 | execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); | 63 | execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); |
@@ -74,6 +75,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { | |||
74 | return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); | 75 | return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); |
75 | } | 76 | } |
76 | close(fd[1]); // close write | 77 | close(fd[1]); // close write |
78 | |||
77 | ssize_t s = 0; | 79 | ssize_t s = 0; |
78 | while ((size_t)s < sizeof(pid_t)) { | 80 | while ((size_t)s < sizeof(pid_t)) { |
79 | s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s); | 81 | s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s); |
diff --git a/sway/security.c b/sway/security.c index ef9e81c4..de54455d 100644 --- a/sway/security.c +++ b/sway/security.c | |||
@@ -1,6 +1,9 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <errno.h> | ||
3 | #include <fcntl.h> | ||
2 | #include <stdlib.h> | 4 | #include <stdlib.h> |
3 | #include <string.h> | 5 | #include <string.h> |
6 | #include <sys/socket.h> | ||
4 | #include "sway/security.h" | 7 | #include "sway/security.h" |
5 | 8 | ||
6 | struct feature_name feature_names[] = { | 9 | struct feature_name feature_names[] = { |
@@ -15,19 +18,58 @@ struct feature_name feature_names[] = { | |||
15 | }; | 18 | }; |
16 | 19 | ||
17 | struct feature_policy *get_feature_policy( | 20 | struct feature_policy *get_feature_policy( |
18 | struct sway_config *config, const char *program) { | 21 | struct sway_config *config, const char *command) { |
19 | if (!program) { | 22 | if (!command) { |
20 | return &config->default_policy; | 23 | return &config->default_policy; |
21 | } | 24 | } |
22 | 25 | ||
23 | struct feature_policy *policy; | 26 | struct feature_policy *policy; |
24 | for (int i = 0; i < config->feature_policies->length; ++i) { | 27 | for (int i = 0; i < config->feature_policies->length; ++i) { |
25 | policy = config->feature_policies->items[i]; | 28 | policy = config->feature_policies->items[i]; |
26 | if (strcmp(policy->program, program) == 0) { | 29 | if (strcmp(policy->command, command) == 0) { |
27 | return policy; | 30 | return policy; |
28 | } | 31 | } |
29 | } | 32 | } |
30 | policy = calloc(1, sizeof(struct feature_policy)); | 33 | policy = calloc(1, sizeof(struct feature_policy)); |
31 | policy->program = strdup(program); | 34 | policy->command = strdup(command); |
32 | return policy; | 35 | return policy; |
33 | } | 36 | } |
37 | |||
38 | struct wl_client *create_secure_client(struct wl_display *display, | ||
39 | int fd, const char *command) { | ||
40 | struct feature_policy *policy; | ||
41 | int i; | ||
42 | for (i = 0; i < config->feature_policies->length; ++i) { | ||
43 | policy = config->feature_policies->items[i]; | ||
44 | if (strcmp(policy->command, command) == 0) { | ||
45 | break; | ||
46 | } | ||
47 | } | ||
48 | if (i == config->feature_policies->length) { | ||
49 | policy = &config->default_policy; | ||
50 | } | ||
51 | // TODO: Something useful with policy | ||
52 | struct wl_client *client = wl_client_create(display, fd); | ||
53 | // TODO: Destroy listener | ||
54 | return client; | ||
55 | } | ||
56 | |||
57 | bool create_client_socket(int sv[2]) { | ||
58 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0 || errno == EINVAL) { | ||
59 | return false; | ||
60 | } | ||
61 | int flags; | ||
62 | if ((flags = fcntl(sv[0], F_GETFD)) == -1) { | ||
63 | return false; | ||
64 | } | ||
65 | if ((fcntl(sv[0], F_SETFD, flags | FD_CLOEXEC)) == -1) { | ||
66 | return false; | ||
67 | } | ||
68 | if ((flags = fcntl(sv[1], F_GETFD)) == -1) { | ||
69 | return false; | ||
70 | } | ||
71 | if ((fcntl(sv[1], F_SETFD, flags | FD_CLOEXEC)) == -1) { | ||
72 | return false; | ||
73 | } | ||
74 | return true; | ||
75 | } | ||