1 |
/* |
2 |
* tomoyo_new_network_test.c |
3 |
* |
4 |
* Testing program for fs/tomoyo_network.c |
5 |
* |
6 |
* Copyright (C) 2005-2008 NTT DATA CORPORATION |
7 |
* |
8 |
* Version: 1.6.5-pre 2008/10/20 |
9 |
* |
10 |
*/ |
11 |
#include "include.h" |
12 |
|
13 |
static int domain_fd = EOF; |
14 |
static const char *policy = ""; |
15 |
static char self_domain[4096] = ""; |
16 |
|
17 |
static int write_policy(void) |
18 |
{ |
19 |
FILE *fp = fopen(proc_policy_domain_policy, "r"); |
20 |
char buffer[8192]; |
21 |
char *cp; |
22 |
int domain_found = 0; |
23 |
int policy_found = 0; |
24 |
memset(buffer, 0, sizeof(buffer)); |
25 |
write(domain_fd, policy, strlen(policy)); |
26 |
write(domain_fd, "\n", 1); |
27 |
if (!fp) { |
28 |
printf("%s : BUG: policy read failed\n", policy); |
29 |
return 0; |
30 |
} |
31 |
while (fgets(buffer, sizeof(buffer) - 1, fp)) { |
32 |
cp = strchr(buffer, '\n'); |
33 |
if (cp) |
34 |
*cp = '\0'; |
35 |
if (!strncmp(buffer, "<kernel>", 8)) |
36 |
domain_found = !strcmp(self_domain, buffer); |
37 |
if (domain_found) { |
38 |
if (!strcmp(buffer, policy)) { |
39 |
policy_found = 1; |
40 |
break; |
41 |
} |
42 |
} |
43 |
} |
44 |
fclose(fp); |
45 |
if (!policy_found) { |
46 |
printf("%s : BUG: policy write failed\n", policy); |
47 |
return 0; |
48 |
} |
49 |
errno = 0; |
50 |
return 1; |
51 |
} |
52 |
|
53 |
static void delete_policy(void) |
54 |
{ |
55 |
write(domain_fd, "delete ", 7); |
56 |
write(domain_fd, policy, strlen(policy)); |
57 |
write(domain_fd, "\n", 1); |
58 |
} |
59 |
|
60 |
static void show_result(int result, char should_success) |
61 |
{ |
62 |
printf("%s : ", policy); |
63 |
if (should_success) { |
64 |
if (result != EOF) |
65 |
printf("OK\n"); |
66 |
else |
67 |
printf("FAILED: %s\n", strerror(errno)); |
68 |
} else { |
69 |
if (result == EOF) { |
70 |
if (errno == EPERM) |
71 |
printf("OK: Permission denied.\n"); |
72 |
else |
73 |
printf("FAILED: %s\n", strerror(errno)); |
74 |
} else { |
75 |
printf("BUG\n"); |
76 |
} |
77 |
} |
78 |
} |
79 |
|
80 |
static void show_result2(int result) |
81 |
{ |
82 |
printf("%s : ", policy); |
83 |
if (result == EOF) { |
84 |
if (errno == ECONNABORTED) |
85 |
printf("OK: Software caused connection abort.\n"); |
86 |
else |
87 |
printf("BUG: %s\n", strerror(errno)); |
88 |
} else { |
89 |
printf("BUG\n"); |
90 |
} |
91 |
} |
92 |
|
93 |
static void stage_network_test(void) |
94 |
{ |
95 |
int i; |
96 |
|
97 |
{ /* IPv4 TCP */ |
98 |
char buffer[1024]; |
99 |
struct sockaddr_in saddr; |
100 |
struct sockaddr_in caddr; |
101 |
socklen_t size = sizeof(saddr); |
102 |
int fd1 = socket(PF_INET, SOCK_STREAM, 0); |
103 |
int fd2 = socket(PF_INET, SOCK_STREAM, 0); |
104 |
int fd3 = EOF; |
105 |
memset(buffer, 0, sizeof(buffer)); |
106 |
policy = buffer; |
107 |
|
108 |
memset(&saddr, 0, sizeof(saddr)); |
109 |
saddr.sin_family = AF_INET; |
110 |
saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
111 |
saddr.sin_port = htons(0); |
112 |
|
113 |
snprintf(buffer, sizeof(buffer) - 1, |
114 |
"allow_network TCP bind 127.0.0.1 0-1"); |
115 |
errno = 0; |
116 |
show_result(bind(fd1, (struct sockaddr *) &saddr, |
117 |
sizeof(saddr)), 0); |
118 |
if (write_policy()) { |
119 |
show_result(bind(fd1, (struct sockaddr *) &saddr, |
120 |
sizeof(saddr)), 1); |
121 |
delete_policy(); |
122 |
} |
123 |
getsockname(fd1, (struct sockaddr *) &saddr, &size); |
124 |
|
125 |
snprintf(buffer, sizeof(buffer) - 1, |
126 |
"allow_network TCP listen 127.0.0.0-127.255.255.255 " |
127 |
"%u-%u", ntohs(saddr.sin_port) - 1, |
128 |
ntohs(saddr.sin_port) + 1); |
129 |
errno = 0; |
130 |
show_result(listen(fd1, 5), 0); |
131 |
if (write_policy()) { |
132 |
show_result(listen(fd1, 5), 1); |
133 |
delete_policy(); |
134 |
} |
135 |
|
136 |
snprintf(buffer, sizeof(buffer) - 1, |
137 |
"allow_network TCP connect 127.0.0.1 %u-%u", |
138 |
ntohs(saddr.sin_port) - 1, ntohs(saddr.sin_port) + 1); |
139 |
errno = 0; |
140 |
show_result(connect(fd2, (struct sockaddr *) &saddr, |
141 |
sizeof(saddr)), 0); |
142 |
if (write_policy()) { |
143 |
show_result(connect(fd2, (struct sockaddr *) &saddr, |
144 |
sizeof(saddr)), 1); |
145 |
delete_policy(); |
146 |
} |
147 |
getsockname(fd2, (struct sockaddr *) &caddr, &size); |
148 |
|
149 |
snprintf(buffer, sizeof(buffer) - 1, |
150 |
"allow_network TCP accept 127.0.0.1 %u-%u", |
151 |
ntohs(caddr.sin_port) - 1, ntohs(caddr.sin_port) + 1); |
152 |
errno = 0; |
153 |
fd3 = accept(fd1, (struct sockaddr *) &caddr, &size); |
154 |
show_result2(fd3); |
155 |
if (fd3 != EOF) |
156 |
close(fd3); |
157 |
|
158 |
close(fd2); |
159 |
fd2 = socket(PF_INET, SOCK_STREAM, 0); |
160 |
snprintf(buffer, sizeof(buffer) - 1, |
161 |
"allow_network TCP connect 127.0.0.0-127.255.255.255 " |
162 |
"%u-%u", ntohs(saddr.sin_port) - 1, |
163 |
ntohs(saddr.sin_port) + 1); |
164 |
if (write_policy()) { |
165 |
connect(fd2, (struct sockaddr *) &saddr, sizeof(saddr)); |
166 |
delete_policy(); |
167 |
} |
168 |
getsockname(fd2, (struct sockaddr *) &caddr, &size); |
169 |
snprintf(buffer, sizeof(buffer) - 1, |
170 |
"allow_network TCP accept 127.0.0.0-127.255.255.255 " |
171 |
"%u-%u", ntohs(caddr.sin_port) - 1, |
172 |
ntohs(caddr.sin_port) + 1); |
173 |
if (write_policy()) { |
174 |
fd3 = accept(fd1, (struct sockaddr *) &caddr, &size); |
175 |
show_result(fd3, 1); |
176 |
delete_policy(); |
177 |
if (fd3 != EOF) |
178 |
close(fd3); |
179 |
} |
180 |
|
181 |
if (fd2 != EOF) |
182 |
close(fd2); |
183 |
if (fd1 != EOF) |
184 |
close(fd1); |
185 |
} |
186 |
|
187 |
i = socket(PF_INET6, SOCK_STREAM, 0); |
188 |
if (i == EOF) |
189 |
return; |
190 |
close(i); |
191 |
|
192 |
{ /* IPv6 TCP */ |
193 |
char buffer[1024]; |
194 |
struct sockaddr_in6 saddr, caddr; |
195 |
socklen_t size = sizeof(saddr); |
196 |
int fd1 = socket(PF_INET6, SOCK_STREAM, 0); |
197 |
int fd2 = socket(PF_INET6, SOCK_STREAM, 0); |
198 |
int fd3 = EOF; |
199 |
memset(buffer, 0, sizeof(buffer)); |
200 |
policy = buffer; |
201 |
|
202 |
memset(&saddr, 0, sizeof(saddr)); |
203 |
saddr.sin6_family = AF_INET6; |
204 |
saddr.sin6_addr = in6addr_loopback; |
205 |
saddr.sin6_port = htons(0); |
206 |
|
207 |
snprintf(buffer, sizeof(buffer) - 1, |
208 |
"allow_network TCP bind 0:0:0:0:0:0:0:1 0-1"); |
209 |
errno = 0; |
210 |
show_result(bind(fd1, (struct sockaddr *) &saddr, |
211 |
sizeof(saddr)), 0); |
212 |
if (write_policy()) { |
213 |
show_result(bind(fd1, (struct sockaddr *) &saddr, |
214 |
sizeof(saddr)), 1); |
215 |
delete_policy(); |
216 |
} |
217 |
getsockname(fd1, (struct sockaddr *) &saddr, &size); |
218 |
|
219 |
snprintf(buffer, sizeof(buffer) - 1, "allow_network TCP listen " |
220 |
"0:0:0:0:0:0:0:0-0:0:0:0:0:0:0:ff %u-%u", |
221 |
ntohs(saddr.sin6_port) - 1, |
222 |
ntohs(saddr.sin6_port) + 1); |
223 |
errno = 0; |
224 |
show_result(listen(fd1, 5), 0); |
225 |
if (write_policy()) { |
226 |
show_result(listen(fd1, 5), 1); |
227 |
delete_policy(); |
228 |
} |
229 |
|
230 |
snprintf(buffer, sizeof(buffer) - 1, |
231 |
"allow_network TCP connect 0:0:0:0:0:0:0:1 %u-%u", |
232 |
ntohs(saddr.sin6_port) - 1, |
233 |
ntohs(saddr.sin6_port) + 1); |
234 |
errno = 0; |
235 |
show_result(connect(fd2, (struct sockaddr *) &saddr, |
236 |
sizeof(saddr)), 0); |
237 |
if (write_policy()) { |
238 |
show_result(connect(fd2, (struct sockaddr *) &saddr, |
239 |
sizeof(saddr)), 1); |
240 |
delete_policy(); |
241 |
} |
242 |
getsockname(fd2, (struct sockaddr *) &caddr, &size); |
243 |
|
244 |
snprintf(buffer, sizeof(buffer) - 1, |
245 |
"allow_network TCP accept 0:0:0:0:0:0:0:1 %u-%u", |
246 |
ntohs(caddr.sin6_port) - 1, |
247 |
ntohs(caddr.sin6_port) + 1); |
248 |
errno = 0; |
249 |
fd3 = accept(fd1, (struct sockaddr *) &caddr, &size); |
250 |
show_result2(fd3); |
251 |
if (fd3 != EOF) |
252 |
close(fd3); |
253 |
|
254 |
close(fd2); |
255 |
fd2 = socket(PF_INET6, SOCK_STREAM, 0); |
256 |
snprintf(buffer, sizeof(buffer) - 1, "allow_network TCP " |
257 |
"connect 0:0:0:0:0:0:0:0-0:0:0:0:0:0:0:ff %u-%u", |
258 |
ntohs(saddr.sin6_port) - 1, |
259 |
ntohs(saddr.sin6_port) + 1); |
260 |
if (write_policy()) { |
261 |
connect(fd2, (struct sockaddr *) &saddr, sizeof(saddr)); |
262 |
delete_policy(); |
263 |
} |
264 |
getsockname(fd2, (struct sockaddr *) &caddr, &size); |
265 |
snprintf(buffer, sizeof(buffer) - 1, "allow_network TCP accept " |
266 |
"0:0:0:0:0:0:0:0-0:0:0:0:0:0:0:ff %u-%u", |
267 |
ntohs(caddr.sin6_port) - 1, |
268 |
ntohs(caddr.sin6_port) + 1); |
269 |
if (write_policy()) { |
270 |
fd3 = accept(fd1, (struct sockaddr *) &caddr, &size); |
271 |
show_result(fd3, 1); |
272 |
delete_policy(); |
273 |
if (fd3 != EOF) |
274 |
close(fd3); |
275 |
} |
276 |
|
277 |
if (fd2 != EOF) |
278 |
close(fd2); |
279 |
if (fd1 != EOF) |
280 |
close(fd1); |
281 |
} |
282 |
} |
283 |
|
284 |
int main(int argc, char *argv[]) |
285 |
{ |
286 |
ccs_test_init(); |
287 |
domain_fd = open(proc_policy_domain_policy, O_WRONLY); |
288 |
{ |
289 |
int self_fd = open(proc_policy_self_domain, O_RDONLY); |
290 |
memset(self_domain, 0, sizeof(self_domain)); |
291 |
read(self_fd, self_domain, sizeof(self_domain) - 1); |
292 |
close(self_fd); |
293 |
write(domain_fd, self_domain, strlen(self_domain)); |
294 |
write(domain_fd, "\n", 1); |
295 |
} |
296 |
write_status("MAC_FOR_NETWORK=enforcing\n"); |
297 |
write_status("MAX_REJECT_LOG=1024\n"); |
298 |
stage_network_test(); |
299 |
close(domain_fd); |
300 |
clear_status(); |
301 |
return 0; |
302 |
} |