diff options
-rw-r--r-- | common/util.c | 41 | ||||
-rw-r--r-- | include/sway/security.h | 8 | ||||
-rw-r--r-- | include/util.h | 8 | ||||
-rw-r--r-- | sway/commands.c | 2 | ||||
-rw-r--r-- | sway/commands/ipc.c | 10 | ||||
-rw-r--r-- | sway/commands/permit.c | 58 | ||||
-rw-r--r-- | sway/extensions.c | 8 | ||||
-rw-r--r-- | sway/handlers.c | 10 | ||||
-rw-r--r-- | sway/ipc-server.c | 2 | ||||
-rw-r--r-- | sway/security.c | 72 |
10 files changed, 179 insertions, 40 deletions
diff --git a/common/util.c b/common/util.c index 12ed0cdc..a9e6a9c2 100644 --- a/common/util.c +++ b/common/util.c | |||
@@ -1,3 +1,7 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <sys/types.h> | ||
3 | #include <sys/stat.h> | ||
4 | #include <unistd.h> | ||
1 | #include <math.h> | 5 | #include <math.h> |
2 | #include <stdint.h> | 6 | #include <stdint.h> |
3 | #include <stdio.h> | 7 | #include <stdio.h> |
@@ -118,3 +122,40 @@ uint32_t parse_color(const char *color) { | |||
118 | } | 122 | } |
119 | return res; | 123 | return res; |
120 | } | 124 | } |
125 | |||
126 | char* resolve_path(const char* path) { | ||
127 | struct stat sb; | ||
128 | ssize_t r; | ||
129 | int i; | ||
130 | char *current = NULL; | ||
131 | char *resolved = NULL; | ||
132 | |||
133 | if(!(current = strdup(path))) { | ||
134 | return NULL; | ||
135 | } | ||
136 | for (i = 0; i < 16; ++i) { | ||
137 | if (lstat(current, &sb) == -1) { | ||
138 | goto failed; | ||
139 | } | ||
140 | if((sb.st_mode & S_IFMT) != S_IFLNK) { | ||
141 | return current; | ||
142 | } | ||
143 | if (!(resolved = malloc(sb.st_size + 1))) { | ||
144 | goto failed; | ||
145 | } | ||
146 | r = readlink(current, resolved, sb.st_size); | ||
147 | if (r == -1 || r > sb.st_size) { | ||
148 | goto failed; | ||
149 | } | ||
150 | resolved[r] = '\0'; | ||
151 | free(current); | ||
152 | current = strdup(resolved); | ||
153 | free(resolved); | ||
154 | resolved = NULL; | ||
155 | } | ||
156 | |||
157 | failed: | ||
158 | free(resolved); | ||
159 | free(current); | ||
160 | return NULL; | ||
161 | } \ No newline at end of file | ||
diff --git a/include/sway/security.h b/include/sway/security.h index c3a5cfd4..0edffdfa 100644 --- a/include/sway/security.h +++ b/include/sway/security.h | |||
@@ -3,9 +3,11 @@ | |||
3 | #include <unistd.h> | 3 | #include <unistd.h> |
4 | #include "sway/config.h" | 4 | #include "sway/config.h" |
5 | 5 | ||
6 | uint32_t get_feature_policy(pid_t pid); | 6 | uint32_t get_feature_policy_mask(pid_t pid); |
7 | uint32_t get_ipc_policy(pid_t pid); | 7 | uint32_t get_ipc_policy_mask(pid_t pid); |
8 | uint32_t get_command_policy(const char *cmd); | 8 | uint32_t get_command_policy_mask(const char *cmd); |
9 | |||
10 | struct feature_policy *get_feature_policy(const char *name); | ||
9 | 11 | ||
10 | const char *command_policy_str(enum command_context context); | 12 | const char *command_policy_str(enum command_context context); |
11 | 13 | ||
diff --git a/include/util.h b/include/util.h index 839af265..e5365458 100644 --- a/include/util.h +++ b/include/util.h | |||
@@ -49,4 +49,12 @@ pid_t get_parent_pid(pid_t pid); | |||
49 | */ | 49 | */ |
50 | uint32_t parse_color(const char *color); | 50 | uint32_t parse_color(const char *color); |
51 | 51 | ||
52 | /** | ||
53 | * Given a path string, recurseively resolves any symlinks to their targets | ||
54 | * (which may be a file, directory) and returns the result. | ||
55 | * argument is returned. Caller must free the returned buffer. | ||
56 | * If an error occures, if the path does not exist or if the path corresponds | ||
57 | * to a dangling symlink, NULL is returned. | ||
58 | */ | ||
59 | char* resolve_path(const char* path); | ||
52 | #endif | 60 | #endif |
diff --git a/sway/commands.c b/sway/commands.c index 17c7d717..4d7af301 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -437,7 +437,7 @@ struct cmd_results *handle_command(char *_exec, enum command_context context) { | |||
437 | free_argv(argc, argv); | 437 | free_argv(argc, argv); |
438 | goto cleanup; | 438 | goto cleanup; |
439 | } | 439 | } |
440 | if (!(get_command_policy(argv[0]) & context)) { | 440 | if (!(get_command_policy_mask(argv[0]) & context)) { |
441 | if (results) { | 441 | if (results) { |
442 | free_cmd_results(results); | 442 | free_cmd_results(results); |
443 | } | 443 | } |
diff --git a/sway/commands/ipc.c b/sway/commands/ipc.c index 8a7b849f..f0b3035a 100644 --- a/sway/commands/ipc.c +++ b/sway/commands/ipc.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
1 | #include <stdio.h> | 2 | #include <stdio.h> |
2 | #include <string.h> | 3 | #include <string.h> |
3 | #include "sway/security.h" | 4 | #include "sway/security.h" |
@@ -18,8 +19,14 @@ struct cmd_results *cmd_ipc(int argc, char **argv) { | |||
18 | return error; | 19 | return error; |
19 | } | 20 | } |
20 | 21 | ||
21 | const char *program = argv[0]; | 22 | char *program = NULL; |
22 | 23 | ||
24 | if (!strcmp(argv[0], "*")) { | ||
25 | program = strdup(argv[0]); | ||
26 | } else if (!(program = resolve_path(argv[0]))) { | ||
27 | return cmd_results_new( | ||
28 | CMD_INVALID, "ipc", "Unable to resolve IPC Policy target."); | ||
29 | } | ||
23 | if (config->reading && strcmp("{", argv[1]) != 0) { | 30 | if (config->reading && strcmp("{", argv[1]) != 0) { |
24 | return cmd_results_new(CMD_INVALID, "ipc", | 31 | return cmd_results_new(CMD_INVALID, "ipc", |
25 | "Expected '{' at start of IPC config definition."); | 32 | "Expected '{' at start of IPC config definition."); |
@@ -32,6 +39,7 @@ struct cmd_results *cmd_ipc(int argc, char **argv) { | |||
32 | current_policy = alloc_ipc_policy(program); | 39 | current_policy = alloc_ipc_policy(program); |
33 | list_add(config->ipc_policies, current_policy); | 40 | list_add(config->ipc_policies, current_policy); |
34 | 41 | ||
42 | free(program); | ||
35 | return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL); | 43 | return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL); |
36 | } | 44 | } |
37 | 45 | ||
diff --git a/sway/commands/permit.c b/sway/commands/permit.c index e2bec2e2..66fa4e2a 100644 --- a/sway/commands/permit.c +++ b/sway/commands/permit.c | |||
@@ -1,7 +1,9 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
1 | #include <string.h> | 2 | #include <string.h> |
2 | #include "sway/commands.h" | 3 | #include "sway/commands.h" |
3 | #include "sway/config.h" | 4 | #include "sway/config.h" |
4 | #include "sway/security.h" | 5 | #include "sway/security.h" |
6 | #include "util.h" | ||
5 | #include "log.h" | 7 | #include "log.h" |
6 | 8 | ||
7 | static enum secure_feature get_features(int argc, char **argv, | 9 | static enum secure_feature get_features(int argc, char **argv, |
@@ -38,25 +40,6 @@ static enum secure_feature get_features(int argc, char **argv, | |||
38 | return features; | 40 | return features; |
39 | } | 41 | } |
40 | 42 | ||
41 | static struct feature_policy *get_policy(const char *name) { | ||
42 | struct feature_policy *policy = NULL; | ||
43 | for (int i = 0; i < config->feature_policies->length; ++i) { | ||
44 | struct feature_policy *p = config->feature_policies->items[i]; | ||
45 | if (strcmp(p->program, name) == 0) { | ||
46 | policy = p; | ||
47 | break; | ||
48 | } | ||
49 | } | ||
50 | if (!policy) { | ||
51 | policy = alloc_feature_policy(name); | ||
52 | if (!policy) { | ||
53 | sway_abort("Unable to allocate security policy"); | ||
54 | } | ||
55 | list_add(config->feature_policies, policy); | ||
56 | } | ||
57 | return policy; | ||
58 | } | ||
59 | |||
60 | struct cmd_results *cmd_permit(int argc, char **argv) { | 43 | struct cmd_results *cmd_permit(int argc, char **argv) { |
61 | struct cmd_results *error = NULL; | 44 | struct cmd_results *error = NULL; |
62 | if ((error = checkarg(argc, "permit", EXPECTED_MORE_THAN, 1))) { | 45 | if ((error = checkarg(argc, "permit", EXPECTED_MORE_THAN, 1))) { |
@@ -66,12 +49,29 @@ struct cmd_results *cmd_permit(int argc, char **argv) { | |||
66 | return error; | 49 | return error; |
67 | } | 50 | } |
68 | 51 | ||
69 | struct feature_policy *policy = get_policy(argv[0]); | 52 | bool assign_perms = true; |
70 | policy->features |= get_features(argc, argv, &error); | 53 | char *program = NULL; |
71 | 54 | ||
55 | if (!strcmp(argv[0], "*")) { | ||
56 | program = strdup(argv[0]); | ||
57 | } else { | ||
58 | program = resolve_path(argv[0]); | ||
59 | } | ||
60 | if (!program) { | ||
61 | sway_assert(program, "Unable to resolve IPC permit target '%s'." | ||
62 | " will issue empty policy", argv[0]); | ||
63 | assign_perms = false; | ||
64 | program = strdup(argv[0]); | ||
65 | } | ||
66 | |||
67 | struct feature_policy *policy = get_feature_policy(program); | ||
68 | if (assign_perms) { | ||
69 | policy->features |= get_features(argc, argv, &error); | ||
70 | } | ||
72 | sway_log(L_DEBUG, "Permissions granted to %s for features %d", | 71 | sway_log(L_DEBUG, "Permissions granted to %s for features %d", |
73 | policy->program, policy->features); | 72 | policy->program, policy->features); |
74 | 73 | ||
74 | free(program); | ||
75 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 75 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
76 | } | 76 | } |
77 | 77 | ||
@@ -84,11 +84,25 @@ struct cmd_results *cmd_reject(int argc, char **argv) { | |||
84 | return error; | 84 | return error; |
85 | } | 85 | } |
86 | 86 | ||
87 | struct feature_policy *policy = get_policy(argv[0]); | 87 | char *program = NULL; |
88 | if (!strcmp(argv[0], "*")) { | ||
89 | program = strdup(argv[0]); | ||
90 | } else { | ||
91 | program = resolve_path(argv[0]); | ||
92 | } | ||
93 | if (!program) { | ||
94 | // Punt | ||
95 | sway_log(L_INFO, "Unable to resolve IPC reject target '%s'." | ||
96 | " Will use provided path", argv[0]); | ||
97 | program = strdup(argv[0]); | ||
98 | } | ||
99 | |||
100 | struct feature_policy *policy = get_feature_policy(program); | ||
88 | policy->features &= ~get_features(argc, argv, &error); | 101 | policy->features &= ~get_features(argc, argv, &error); |
89 | 102 | ||
90 | sway_log(L_DEBUG, "Permissions granted to %s for features %d", | 103 | sway_log(L_DEBUG, "Permissions granted to %s for features %d", |
91 | policy->program, policy->features); | 104 | policy->program, policy->features); |
92 | 105 | ||
106 | free(program); | ||
93 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 107 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
94 | } | 108 | } |
diff --git a/sway/extensions.c b/sway/extensions.c index 15d2f971..96957dbf 100644 --- a/sway/extensions.c +++ b/sway/extensions.c | |||
@@ -86,7 +86,7 @@ static void set_background(struct wl_client *client, struct wl_resource *resourc | |||
86 | struct wl_resource *_output, struct wl_resource *surface) { | 86 | struct wl_resource *_output, struct wl_resource *surface) { |
87 | pid_t pid; | 87 | pid_t pid; |
88 | wl_client_get_credentials(client, &pid, NULL, NULL); | 88 | wl_client_get_credentials(client, &pid, NULL, NULL); |
89 | if (!(get_feature_policy(pid) & FEATURE_BACKGROUND)) { | 89 | if (!(get_feature_policy_mask(pid) & FEATURE_BACKGROUND)) { |
90 | sway_log(L_INFO, "Denying background feature to %d", pid); | 90 | sway_log(L_INFO, "Denying background feature to %d", pid); |
91 | return; | 91 | return; |
92 | } | 92 | } |
@@ -114,7 +114,7 @@ static void set_panel(struct wl_client *client, struct wl_resource *resource, | |||
114 | struct wl_resource *_output, struct wl_resource *surface) { | 114 | struct wl_resource *_output, struct wl_resource *surface) { |
115 | pid_t pid; | 115 | pid_t pid; |
116 | wl_client_get_credentials(client, &pid, NULL, NULL); | 116 | wl_client_get_credentials(client, &pid, NULL, NULL); |
117 | if (!(get_feature_policy(pid) & FEATURE_PANEL)) { | 117 | if (!(get_feature_policy_mask(pid) & FEATURE_PANEL)) { |
118 | sway_log(L_INFO, "Denying panel feature to %d", pid); | 118 | sway_log(L_INFO, "Denying panel feature to %d", pid); |
119 | return; | 119 | return; |
120 | } | 120 | } |
@@ -152,7 +152,7 @@ static void desktop_ready(struct wl_client *client, struct wl_resource *resource | |||
152 | static void set_panel_position(struct wl_client *client, struct wl_resource *resource, uint32_t position) { | 152 | static void set_panel_position(struct wl_client *client, struct wl_resource *resource, uint32_t position) { |
153 | pid_t pid; | 153 | pid_t pid; |
154 | wl_client_get_credentials(client, &pid, NULL, NULL); | 154 | wl_client_get_credentials(client, &pid, NULL, NULL); |
155 | if (!(get_feature_policy(pid) & FEATURE_PANEL)) { | 155 | if (!(get_feature_policy_mask(pid) & FEATURE_PANEL)) { |
156 | sway_log(L_INFO, "Denying panel feature to %d", pid); | 156 | sway_log(L_INFO, "Denying panel feature to %d", pid); |
157 | return; | 157 | return; |
158 | } | 158 | } |
@@ -191,7 +191,7 @@ static void set_lock_surface(struct wl_client *client, struct wl_resource *resou | |||
191 | struct wl_resource *_output, struct wl_resource *surface) { | 191 | struct wl_resource *_output, struct wl_resource *surface) { |
192 | pid_t pid; | 192 | pid_t pid; |
193 | wl_client_get_credentials(client, &pid, NULL, NULL); | 193 | wl_client_get_credentials(client, &pid, NULL, NULL); |
194 | if (!(get_feature_policy(pid) & FEATURE_LOCK)) { | 194 | if (!(get_feature_policy_mask(pid) & FEATURE_LOCK)) { |
195 | sway_log(L_INFO, "Denying lock feature to %d", pid); | 195 | sway_log(L_INFO, "Denying lock feature to %d", pid); |
196 | return; | 196 | return; |
197 | } | 197 | } |
diff --git a/sway/handlers.c b/sway/handlers.c index b61c0a19..a8de135f 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -595,7 +595,7 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s | |||
595 | pid_t pid = wlc_view_get_pid(view); | 595 | pid_t pid = wlc_view_get_pid(view); |
596 | switch (state) { | 596 | switch (state) { |
597 | case WLC_BIT_FULLSCREEN: | 597 | case WLC_BIT_FULLSCREEN: |
598 | if (!(get_feature_policy(pid) & FEATURE_FULLSCREEN)) { | 598 | if (!(get_feature_policy_mask(pid) & FEATURE_FULLSCREEN)) { |
599 | sway_log(L_INFO, "Denying fullscreen to %d (%s)", pid, c->name); | 599 | sway_log(L_INFO, "Denying fullscreen to %d (%s)", pid, c->name); |
600 | break; | 600 | break; |
601 | } | 601 | } |
@@ -811,7 +811,7 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
811 | swayc_t *focused = get_focused_container(&root_container); | 811 | swayc_t *focused = get_focused_container(&root_container); |
812 | if (focused->type == C_VIEW) { | 812 | if (focused->type == C_VIEW) { |
813 | pid_t pid = wlc_view_get_pid(focused->handle); | 813 | pid_t pid = wlc_view_get_pid(focused->handle); |
814 | if (!(get_feature_policy(pid) & FEATURE_KEYBOARD)) { | 814 | if (!(get_feature_policy_mask(pid) & FEATURE_KEYBOARD)) { |
815 | return EVENT_HANDLED; | 815 | return EVENT_HANDLED; |
816 | } | 816 | } |
817 | } | 817 | } |
@@ -875,7 +875,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
875 | swayc_t *focused = get_focused_container(&root_container); | 875 | swayc_t *focused = get_focused_container(&root_container); |
876 | if (focused->type == C_VIEW) { | 876 | if (focused->type == C_VIEW) { |
877 | pid_t pid = wlc_view_get_pid(focused->handle); | 877 | pid_t pid = wlc_view_get_pid(focused->handle); |
878 | if (!(get_feature_policy(pid) & FEATURE_MOUSE)) { | 878 | if (!(get_feature_policy_mask(pid) & FEATURE_MOUSE)) { |
879 | return EVENT_HANDLED; | 879 | return EVENT_HANDLED; |
880 | } | 880 | } |
881 | } | 881 | } |
@@ -953,7 +953,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
953 | if (swayc_is_fullscreen(focused)) { | 953 | if (swayc_is_fullscreen(focused)) { |
954 | if (focused->type == C_VIEW) { | 954 | if (focused->type == C_VIEW) { |
955 | pid_t pid = wlc_view_get_pid(focused->handle); | 955 | pid_t pid = wlc_view_get_pid(focused->handle); |
956 | if (!(get_feature_policy(pid) & FEATURE_MOUSE)) { | 956 | if (!(get_feature_policy_mask(pid) & FEATURE_MOUSE)) { |
957 | return EVENT_HANDLED; | 957 | return EVENT_HANDLED; |
958 | } | 958 | } |
959 | } | 959 | } |
@@ -1001,7 +1001,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
1001 | 1001 | ||
1002 | if (focused->type == C_VIEW) { | 1002 | if (focused->type == C_VIEW) { |
1003 | pid_t pid = wlc_view_get_pid(focused->handle); | 1003 | pid_t pid = wlc_view_get_pid(focused->handle); |
1004 | if (!(get_feature_policy(pid) & FEATURE_MOUSE)) { | 1004 | if (!(get_feature_policy_mask(pid) & FEATURE_MOUSE)) { |
1005 | return EVENT_HANDLED; | 1005 | return EVENT_HANDLED; |
1006 | } | 1006 | } |
1007 | } | 1007 | } |
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 67a3cdc8..dca881fa 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -181,7 +181,7 @@ int ipc_handle_connection(int fd, uint32_t mask, void *data) { | |||
181 | client->event_source = wlc_event_loop_add_fd(client_fd, WLC_EVENT_READABLE, ipc_client_handle_readable, client); | 181 | client->event_source = wlc_event_loop_add_fd(client_fd, WLC_EVENT_READABLE, ipc_client_handle_readable, client); |
182 | 182 | ||
183 | pid_t pid = get_client_pid(client->fd); | 183 | pid_t pid = get_client_pid(client->fd); |
184 | client->security_policy = get_ipc_policy(pid); | 184 | client->security_policy = get_ipc_policy_mask(pid); |
185 | 185 | ||
186 | list_add(ipc_client_list, client); | 186 | list_add(ipc_client_list, client); |
187 | 187 | ||
diff --git a/sway/security.c b/sway/security.c index f8a96ba7..8eab6126 100644 --- a/sway/security.c +++ b/sway/security.c | |||
@@ -1,4 +1,6 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #include <sys/types.h> | ||
3 | #include <sys/stat.h> | ||
2 | #include <string.h> | 4 | #include <string.h> |
3 | #include <unistd.h> | 5 | #include <unistd.h> |
4 | #include <stdio.h> | 6 | #include <stdio.h> |
@@ -6,8 +8,46 @@ | |||
6 | #include "sway/security.h" | 8 | #include "sway/security.h" |
7 | #include "log.h" | 9 | #include "log.h" |
8 | 10 | ||
11 | static bool validate_ipc_target(const char *program) { | ||
12 | struct stat sb; | ||
13 | |||
14 | sway_log(L_DEBUG, "Validating IPC target '%s'", program); | ||
15 | |||
16 | if (!strcmp(program, "*")) { | ||
17 | return true; | ||
18 | } | ||
19 | if (lstat(program, &sb) == -1) { | ||
20 | return false; | ||
21 | } | ||
22 | if (!S_ISREG(sb.st_mode)) { | ||
23 | sway_log(L_ERROR, | ||
24 | "IPC target '%s' MUST be/point at an existing regular file", | ||
25 | program); | ||
26 | return false; | ||
27 | } | ||
28 | if (sb.st_uid != 0) { | ||
29 | #ifdef NDEBUG | ||
30 | sway_log(L_ERROR, "IPC target '%s' MUST be owned by root", program); | ||
31 | return false; | ||
32 | #else | ||
33 | sway_log(L_INFO, "IPC target '%s' MUST be owned by root (waived for debug build)", program); | ||
34 | return true; | ||
35 | #endif | ||
36 | } | ||
37 | if (sb.st_mode & S_IWOTH) { | ||
38 | sway_log(L_ERROR, "IPC target '%s' MUST NOT be world writable", program); | ||
39 | return false; | ||
40 | } | ||
41 | |||
42 | return true; | ||
43 | } | ||
44 | |||
9 | struct feature_policy *alloc_feature_policy(const char *program) { | 45 | struct feature_policy *alloc_feature_policy(const char *program) { |
10 | uint32_t default_policy = 0; | 46 | uint32_t default_policy = 0; |
47 | |||
48 | if (!validate_ipc_target(program)) { | ||
49 | return NULL; | ||
50 | } | ||
11 | for (int i = 0; i < config->feature_policies->length; ++i) { | 51 | for (int i = 0; i < config->feature_policies->length; ++i) { |
12 | struct feature_policy *policy = config->feature_policies->items[i]; | 52 | struct feature_policy *policy = config->feature_policies->items[i]; |
13 | if (strcmp(policy->program, "*") == 0) { | 53 | if (strcmp(policy->program, "*") == 0) { |
@@ -26,11 +66,16 @@ struct feature_policy *alloc_feature_policy(const char *program) { | |||
26 | return NULL; | 66 | return NULL; |
27 | } | 67 | } |
28 | policy->features = default_policy; | 68 | policy->features = default_policy; |
69 | |||
29 | return policy; | 70 | return policy; |
30 | } | 71 | } |
31 | 72 | ||
32 | struct ipc_policy *alloc_ipc_policy(const char *program) { | 73 | struct ipc_policy *alloc_ipc_policy(const char *program) { |
33 | uint32_t default_policy = 0; | 74 | uint32_t default_policy = 0; |
75 | |||
76 | if (!validate_ipc_target(program)) { | ||
77 | return NULL; | ||
78 | } | ||
34 | for (int i = 0; i < config->ipc_policies->length; ++i) { | 79 | for (int i = 0; i < config->ipc_policies->length; ++i) { |
35 | struct ipc_policy *policy = config->ipc_policies->items[i]; | 80 | struct ipc_policy *policy = config->ipc_policies->items[i]; |
36 | if (strcmp(policy->program, "*") == 0) { | 81 | if (strcmp(policy->program, "*") == 0) { |
@@ -49,6 +94,7 @@ struct ipc_policy *alloc_ipc_policy(const char *program) { | |||
49 | return NULL; | 94 | return NULL; |
50 | } | 95 | } |
51 | policy->features = default_policy; | 96 | policy->features = default_policy; |
97 | |||
52 | return policy; | 98 | return policy; |
53 | } | 99 | } |
54 | 100 | ||
@@ -94,7 +140,27 @@ static const char *get_pid_exe(pid_t pid) { | |||
94 | return link; | 140 | return link; |
95 | } | 141 | } |
96 | 142 | ||
97 | uint32_t get_feature_policy(pid_t pid) { | 143 | struct feature_policy *get_feature_policy(const char *name) { |
144 | struct feature_policy *policy = NULL; | ||
145 | |||
146 | for (int i = 0; i < config->feature_policies->length; ++i) { | ||
147 | struct feature_policy *p = config->feature_policies->items[i]; | ||
148 | if (strcmp(p->program, name) == 0) { | ||
149 | policy = p; | ||
150 | break; | ||
151 | } | ||
152 | } | ||
153 | if (!policy) { | ||
154 | policy = alloc_feature_policy(name); | ||
155 | if (!policy) { | ||
156 | sway_abort("Unable to allocate security policy"); | ||
157 | } | ||
158 | list_add(config->feature_policies, policy); | ||
159 | } | ||
160 | return policy; | ||
161 | } | ||
162 | |||
163 | uint32_t get_feature_policy_mask(pid_t pid) { | ||
98 | uint32_t default_policy = 0; | 164 | uint32_t default_policy = 0; |
99 | const char *link = get_pid_exe(pid); | 165 | const char *link = get_pid_exe(pid); |
100 | 166 | ||
@@ -111,7 +177,7 @@ uint32_t get_feature_policy(pid_t pid) { | |||
111 | return default_policy; | 177 | return default_policy; |
112 | } | 178 | } |
113 | 179 | ||
114 | uint32_t get_ipc_policy(pid_t pid) { | 180 | uint32_t get_ipc_policy_mask(pid_t pid) { |
115 | uint32_t default_policy = 0; | 181 | uint32_t default_policy = 0; |
116 | const char *link = get_pid_exe(pid); | 182 | const char *link = get_pid_exe(pid); |
117 | 183 | ||
@@ -128,7 +194,7 @@ uint32_t get_ipc_policy(pid_t pid) { | |||
128 | return default_policy; | 194 | return default_policy; |
129 | } | 195 | } |
130 | 196 | ||
131 | uint32_t get_command_policy(const char *cmd) { | 197 | uint32_t get_command_policy_mask(const char *cmd) { |
132 | uint32_t default_policy = 0; | 198 | uint32_t default_policy = 0; |
133 | 199 | ||
134 | for (int i = 0; i < config->command_policies->length; ++i) { | 200 | for (int i = 0; i < config->command_policies->length; ++i) { |