aboutsummaryrefslogtreecommitdiffstats
path: root/sway/security.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2017-11-18 11:22:02 -0500
committerLibravatar Drew DeVault <sir@cmpwn.com>2017-11-18 11:22:02 -0500
commit733993a651c71f7e2198d505960d6bbd31e0e107 (patch)
treee51732c5872b624e73355f9e5b3f762101f3cd0d /sway/security.c
parentInitial (awful) pass on xdg shell support (diff)
downloadsway-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.c228
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
11static 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
45struct 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
73struct 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
101struct 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
115static 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
143struct 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
163uint32_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
180uint32_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
197uint32_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
213const 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}