diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-11-18 11:22:02 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2017-11-18 11:22:02 -0500 |
commit | 733993a651c71f7e2198d505960d6bbd31e0e107 (patch) | |
tree | e51732c5872b624e73355f9e5b3f762101f3cd0d /sway/security.c | |
parent | Initial (awful) pass on xdg shell support (diff) | |
download | sway-733993a651c71f7e2198d505960d6bbd31e0e107.tar.gz sway-733993a651c71f7e2198d505960d6bbd31e0e107.tar.zst sway-733993a651c71f7e2198d505960d6bbd31e0e107.zip |
Move everything to sway/old/
Diffstat (limited to 'sway/security.c')
-rw-r--r-- | sway/security.c | 228 |
1 files changed, 0 insertions, 228 deletions
diff --git a/sway/security.c b/sway/security.c deleted file mode 100644 index fcd70f9d..00000000 --- a/sway/security.c +++ /dev/null | |||
@@ -1,228 +0,0 @@ | |||
1 | #define _XOPEN_SOURCE 700 | ||
2 | #include <sys/types.h> | ||
3 | #include <sys/stat.h> | ||
4 | #include <string.h> | ||
5 | #include <unistd.h> | ||
6 | #include <stdio.h> | ||
7 | #include "sway/config.h" | ||
8 | #include "sway/security.h" | ||
9 | #include "log.h" | ||
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 | |||
45 | struct feature_policy *alloc_feature_policy(const char *program) { | ||
46 | uint32_t default_policy = 0; | ||
47 | |||
48 | if (!validate_ipc_target(program)) { | ||
49 | return NULL; | ||
50 | } | ||
51 | for (int i = 0; i < config->feature_policies->length; ++i) { | ||
52 | struct feature_policy *policy = config->feature_policies->items[i]; | ||
53 | if (strcmp(policy->program, "*") == 0) { | ||
54 | default_policy = policy->features; | ||
55 | break; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | struct feature_policy *policy = malloc(sizeof(struct feature_policy)); | ||
60 | if (!policy) { | ||
61 | return NULL; | ||
62 | } | ||
63 | policy->program = strdup(program); | ||
64 | if (!policy->program) { | ||
65 | free(policy); | ||
66 | return NULL; | ||
67 | } | ||
68 | policy->features = default_policy; | ||
69 | |||
70 | return policy; | ||
71 | } | ||
72 | |||
73 | struct ipc_policy *alloc_ipc_policy(const char *program) { | ||
74 | uint32_t default_policy = 0; | ||
75 | |||
76 | if (!validate_ipc_target(program)) { | ||
77 | return NULL; | ||
78 | } | ||
79 | for (int i = 0; i < config->ipc_policies->length; ++i) { | ||
80 | struct ipc_policy *policy = config->ipc_policies->items[i]; | ||
81 | if (strcmp(policy->program, "*") == 0) { | ||
82 | default_policy = policy->features; | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | struct ipc_policy *policy = malloc(sizeof(struct ipc_policy)); | ||
88 | if (!policy) { | ||
89 | return NULL; | ||
90 | } | ||
91 | policy->program = strdup(program); | ||
92 | if (!policy->program) { | ||
93 | free(policy); | ||
94 | return NULL; | ||
95 | } | ||
96 | policy->features = default_policy; | ||
97 | |||
98 | return policy; | ||
99 | } | ||
100 | |||
101 | struct command_policy *alloc_command_policy(const char *command) { | ||
102 | struct command_policy *policy = malloc(sizeof(struct command_policy)); | ||
103 | if (!policy) { | ||
104 | return NULL; | ||
105 | } | ||
106 | policy->command = strdup(command); | ||
107 | if (!policy->command) { | ||
108 | free(policy); | ||
109 | return NULL; | ||
110 | } | ||
111 | policy->context = 0; | ||
112 | return policy; | ||
113 | } | ||
114 | |||
115 | static const char *get_pid_exe(pid_t pid) { | ||
116 | #ifdef __FreeBSD__ | ||
117 | const char *fmt = "/proc/%d/file"; | ||
118 | #else | ||
119 | const char *fmt = "/proc/%d/exe"; | ||
120 | #endif | ||
121 | int pathlen = snprintf(NULL, 0, fmt, pid); | ||
122 | char *path = malloc(pathlen + 1); | ||
123 | if (path) { | ||
124 | snprintf(path, pathlen + 1, fmt, pid); | ||
125 | } | ||
126 | |||
127 | static char link[2048]; | ||
128 | |||
129 | ssize_t len = !path ? -1 : readlink(path, link, sizeof(link)); | ||
130 | if (len < 0) { | ||
131 | sway_log(L_INFO, | ||
132 | "WARNING: unable to read %s for security check. Using default policy.", | ||
133 | path); | ||
134 | strcpy(link, "*"); | ||
135 | } else { | ||
136 | link[len] = '\0'; | ||
137 | } | ||
138 | free(path); | ||
139 | |||
140 | return link; | ||
141 | } | ||
142 | |||
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 | sway_assert(policy, "Unable to allocate security policy"); | ||
156 | if (policy) { | ||
157 | list_add(config->feature_policies, policy); | ||
158 | } | ||
159 | } | ||
160 | return policy; | ||
161 | } | ||
162 | |||
163 | uint32_t get_feature_policy_mask(pid_t pid) { | ||
164 | uint32_t default_policy = 0; | ||
165 | const char *link = get_pid_exe(pid); | ||
166 | |||
167 | for (int i = 0; i < config->feature_policies->length; ++i) { | ||
168 | struct feature_policy *policy = config->feature_policies->items[i]; | ||
169 | if (strcmp(policy->program, "*") == 0) { | ||
170 | default_policy = policy->features; | ||
171 | } | ||
172 | if (strcmp(policy->program, link) == 0) { | ||
173 | return policy->features; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | return default_policy; | ||
178 | } | ||
179 | |||
180 | uint32_t get_ipc_policy_mask(pid_t pid) { | ||
181 | uint32_t default_policy = 0; | ||
182 | const char *link = get_pid_exe(pid); | ||
183 | |||
184 | for (int i = 0; i < config->ipc_policies->length; ++i) { | ||
185 | struct ipc_policy *policy = config->ipc_policies->items[i]; | ||
186 | if (strcmp(policy->program, "*") == 0) { | ||
187 | default_policy = policy->features; | ||
188 | } | ||
189 | if (strcmp(policy->program, link) == 0) { | ||
190 | return policy->features; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | return default_policy; | ||
195 | } | ||
196 | |||
197 | uint32_t get_command_policy_mask(const char *cmd) { | ||
198 | uint32_t default_policy = 0; | ||
199 | |||
200 | for (int i = 0; i < config->command_policies->length; ++i) { | ||
201 | struct command_policy *policy = config->command_policies->items[i]; | ||
202 | if (strcmp(policy->command, "*") == 0) { | ||
203 | default_policy = policy->context; | ||
204 | } | ||
205 | if (strcmp(policy->command, cmd) == 0) { | ||
206 | return policy->context; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | return default_policy; | ||
211 | } | ||
212 | |||
213 | const char *command_policy_str(enum command_context context) { | ||
214 | switch (context) { | ||
215 | case CONTEXT_ALL: | ||
216 | return "all"; | ||
217 | case CONTEXT_CONFIG: | ||
218 | return "config"; | ||
219 | case CONTEXT_BINDING: | ||
220 | return "binding"; | ||
221 | case CONTEXT_IPC: | ||
222 | return "IPC"; | ||
223 | case CONTEXT_CRITERIA: | ||
224 | return "criteria"; | ||
225 | default: | ||
226 | return "unknown"; | ||
227 | } | ||
228 | } | ||