オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Contents of /trunk/1.6.x/ccs-patch/fs/tomoyo_network.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 906 - (show annotations) (download) (as text)
Fri Jan 18 03:40:52 2008 UTC (16 years, 4 months ago) by kumaneko
File MIME type: text/x-csrc
File size: 21318 byte(s)


1 /*
2 * fs/tomoyo_network.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2008 NTT DATA CORPORATION
7 *
8 * Version: 1.6.0-pre 2008/01/18
9 *
10 * This file is applicable to both 2.4.30 and 2.6.11 and later.
11 * See README.ccs for ChangeLog.
12 *
13 */
14 /***** TOMOYO Linux start. *****/
15
16 #include <linux/ccs_common.h>
17 #include <linux/tomoyo.h>
18 #include <linux/realpath.h>
19 #include <net/ip.h>
20
21 /************************* VARIABLES *************************/
22
23 extern struct mutex domain_acl_lock;
24
25 /************************* AUDIT FUNCTIONS *************************/
26
27 static int AuditNetworkLog(const bool is_ipv6, const char *operation, const u32 *address, const u16 port, const bool is_granted, const u8 profile, const u8 mode)
28 {
29 char *buf;
30 int len = 256;
31 if (CanSaveAuditLog(is_granted) < 0) return -ENOMEM;
32 if ((buf = InitAuditLog(&len, profile, mode)) == NULL) return -ENOMEM;
33 snprintf(buf + strlen(buf), len - strlen(buf) - 1, KEYWORD_ALLOW_NETWORK "%s ", operation);
34 if (is_ipv6) {
35 print_ipv6(buf + strlen(buf), len - strlen(buf), (const struct in6_addr *) address);
36 } else {
37 u32 ip = *address;
38 snprintf(buf + strlen(buf), len - strlen(buf) - 1, "%u.%u.%u.%u", NIPQUAD(ip));
39 }
40 snprintf(buf + strlen(buf), len - strlen(buf) - 1, " %u\n", port);
41 return WriteAuditLog(buf, is_granted);
42 }
43
44 /************************* UTILITY FUNCTIONS *************************/
45
46 /* Keep the given IPv6 address on the RAM. The RAM is shared, so NEVER try to modify or kfree() the returned address. */
47 static const struct in6_addr *SaveIPv6Address(const struct in6_addr *addr)
48 {
49 static const u8 block_size = 16;
50 struct addr_list {
51 struct in6_addr addr[block_size];
52 struct list1_head list;
53 u32 in_use_count;
54 };
55 static LIST1_HEAD(address_list);
56 struct addr_list *ptr;
57 static DEFINE_MUTEX(lock);
58 u8 i = block_size;
59 if (!addr) return NULL;
60 mutex_lock(&lock);
61 list1_for_each_entry(ptr, &address_list, list) {
62 for (i = 0; i < ptr->in_use_count; i++) {
63 if (memcmp(&ptr->addr[i], addr, sizeof(*addr)) == 0) goto ok;
64 }
65 if (i < block_size) break;
66 }
67 if (i == block_size) {
68 ptr = alloc_element(sizeof(*ptr));
69 if (!ptr) goto ok;
70 list1_add_tail_mb(&ptr->list, &address_list);
71 i = 0;
72 }
73 ptr->addr[ptr->in_use_count++] = *addr;
74 ok:
75 mutex_unlock(&lock);
76 return ptr ? &ptr->addr[i] : NULL;
77 }
78
79 /************************* ADDRESS GROUP HANDLER *************************/
80
81 static LIST1_HEAD(address_group_list);
82
83 static int AddAddressGroupEntry(const char *group_name, const bool is_ipv6, const u16 *min_address, const u16 *max_address, const bool is_delete)
84 {
85 static DEFINE_MUTEX(lock);
86 struct address_group_entry *new_group, *group;
87 struct address_group_member *new_member, *member;
88 const struct path_info *saved_group_name;
89 const struct in6_addr *saved_min_address = NULL, *saved_max_address = NULL;
90 int error = -ENOMEM;
91 bool found = 0;
92 if (!IsCorrectPath(group_name, 0, 0, 0, __FUNCTION__) || !group_name[0]) return -EINVAL;
93 if ((saved_group_name = SaveName(group_name)) == NULL) return -ENOMEM;
94 if (is_ipv6) {
95 if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL
96 || (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address)) == NULL) return -ENOMEM;
97 }
98 mutex_lock(&lock);
99 list1_for_each_entry(group, &address_group_list, list) {
100 if (saved_group_name != group->group_name) continue;
101 list1_for_each_entry(member, &group->address_group_member_list, list) {
102 if (member->is_ipv6 != is_ipv6) continue;
103 if (is_ipv6) {
104 if (member->min.ipv6 != saved_min_address || member->max.ipv6 != saved_max_address) continue;
105 } else {
106 if (member->min.ipv4 != * (u32 *) min_address || member->max.ipv4 != * (u32 *) max_address) continue;
107 }
108 member->is_deleted = is_delete;
109 error = 0;
110 goto out;
111 }
112 found = 1;
113 break;
114 }
115 if (is_delete) {
116 error = -ENOENT;
117 goto out;
118 }
119 if (!found) {
120 if ((new_group = alloc_element(sizeof(*new_group))) == NULL) goto out;
121 INIT_LIST1_HEAD(&new_group->address_group_member_list);
122 new_group->group_name = saved_group_name;
123 list1_add_tail_mb(&new_group->list, &address_group_list);
124 group = new_group;
125 }
126 if ((new_member = alloc_element(sizeof(*new_member))) == NULL) goto out;
127 new_member->is_ipv6 = is_ipv6;
128 if (is_ipv6) {
129 new_member->min.ipv6 = saved_min_address;
130 new_member->max.ipv6 = saved_max_address;
131 } else {
132 new_member->min.ipv4 = * (u32 *) min_address;
133 new_member->max.ipv4 = * (u32 *) max_address;
134 }
135 list1_add_tail_mb(&new_member->list, &group->address_group_member_list);
136 error = 0;
137 out:
138 mutex_unlock(&lock);
139 return error;
140 }
141
142 int AddAddressGroupPolicy(char *data, const bool is_delete)
143 {
144 u8 count;
145 bool is_ipv6;
146 u16 min_address[8], max_address[8];
147 char *cp = strchr(data, ' ');
148 if (!cp) return -EINVAL;
149 *cp++ = '\0';
150 if ((count = sscanf(cp, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
151 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
152 &min_address[4], &min_address[5], &min_address[6], &min_address[7],
153 &max_address[0], &max_address[1], &max_address[2], &max_address[3],
154 &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {
155 u8 i;
156 for (i = 0; i < 8; i++) {
157 min_address[i] = htons(min_address[i]);
158 max_address[i] = htons(max_address[i]);
159 }
160 if (count == 8) memmove(max_address, min_address, sizeof(min_address));
161 is_ipv6 = 1;
162 } else if ((count = sscanf(cp, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
163 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
164 &max_address[0], &max_address[1], &max_address[2], &max_address[3])) == 4 || count == 8) {
165 u32 ip = ((((u8) min_address[0]) << 24) + (((u8) min_address[1]) << 16) + (((u8) min_address[2]) << 8) + (u8) min_address[3]);
166 * (u32 *) min_address = ip;
167 if (count == 8) ip = ((((u8) max_address[0]) << 24) + (((u8) max_address[1]) << 16) + (((u8) max_address[2]) << 8) + (u8) max_address[3]);
168 * (u32 *) max_address = ip;
169 is_ipv6 = 0;
170 } else {
171 return -EINVAL;
172 }
173 return AddAddressGroupEntry(data, is_ipv6, min_address, max_address, is_delete);
174 }
175
176 static struct address_group_entry *FindOrAssignNewAddressGroup(const char *group_name)
177 {
178 u8 i;
179 struct address_group_entry *group;
180 for (i = 0; i <= 1; i++) {
181 list1_for_each_entry(group, &address_group_list, list) {
182 if (strcmp(group_name, group->group_name->name) == 0) return group;
183 }
184 if (i == 0) {
185 const u16 dummy[2] = { 0, 0 };
186 AddAddressGroupEntry(group_name, 0, dummy, dummy, 0);
187 AddAddressGroupEntry(group_name, 0, dummy, dummy, 1);
188 }
189 }
190 return NULL;
191 }
192
193 static bool AddressMatchesToGroup(const bool is_ipv6, const u32 *address, const struct address_group_entry *group)
194 {
195 struct address_group_member *member;
196 const u32 ip = ntohl(*address);
197 list1_for_each_entry(member, &group->address_group_member_list, list) {
198 if (member->is_deleted) continue;
199 if (member->is_ipv6) {
200 if (is_ipv6 && memcmp(member->min.ipv6, address, 16) <= 0 && memcmp(address, member->max.ipv6, 16) <= 0) return 1;
201 } else {
202 if (!is_ipv6 && member->min.ipv4 <= ip && ip <= member->max.ipv4) return 1;
203 }
204 }
205 return 0;
206 }
207
208 int ReadAddressGroupPolicy(struct io_buffer *head)
209 {
210 struct list1_head *gpos;
211 struct list1_head *mpos;
212 list1_for_each_cookie(gpos, head->read_var1, &address_group_list) {
213 struct address_group_entry *group;
214 group = list1_entry(gpos, struct address_group_entry, list);
215 list1_for_each_cookie(mpos, head->read_var2, &group->address_group_member_list) {
216 char buf[128];
217 struct address_group_member *member;
218 member = list1_entry(mpos, struct address_group_member, list);
219 if (member->is_deleted) continue;
220 if (member->is_ipv6) {
221 const struct in6_addr *min_address = member->min.ipv6, *max_address = member->max.ipv6;
222 print_ipv6(buf, sizeof(buf), min_address);
223 if (min_address != max_address) {
224 char *cp = strchr(buf, '\0');
225 *cp++ = '-';
226 print_ipv6(cp, sizeof(buf) - strlen(buf), max_address);
227 }
228 } else {
229 const u32 min_address = member->min.ipv4, max_address = member->max.ipv4;
230 memset(buf, 0, sizeof(buf));
231 snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(min_address));
232 if (min_address != max_address) {
233 const int len = strlen(buf);
234 snprintf(buf + len, sizeof(buf) - 1 - len, "-%u.%u.%u.%u", HIPQUAD(max_address));
235 }
236 }
237 if (io_printf(head, KEYWORD_ADDRESS_GROUP "%s %s\n", group->group_name->name, buf)) return -ENOMEM;
238 }
239 }
240 return 0;
241 }
242
243 /************************* NETWORK NETWORK ACL HANDLER *************************/
244
245 #if !defined(NIP6)
246 #define NIP6(addr) \
247 ntohs((addr).s6_addr16[0]), \
248 ntohs((addr).s6_addr16[1]), \
249 ntohs((addr).s6_addr16[2]), \
250 ntohs((addr).s6_addr16[3]), \
251 ntohs((addr).s6_addr16[4]), \
252 ntohs((addr).s6_addr16[5]), \
253 ntohs((addr).s6_addr16[6]), \
254 ntohs((addr).s6_addr16[7])
255 #endif
256
257 char *print_ipv6(char *buffer, const int buffer_len, const struct in6_addr *ip)
258 {
259 memset(buffer, 0, buffer_len);
260 snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));
261 return buffer;
262 }
263
264 const char *net_operation2keyword(const u8 operation)
265 {
266 const char *keyword = "unknown";
267 switch (operation) {
268 case NETWORK_ACL_UDP_BIND:
269 keyword = "UDP bind";
270 break;
271 case NETWORK_ACL_UDP_CONNECT:
272 keyword = "UDP connect";
273 break;
274 case NETWORK_ACL_TCP_BIND:
275 keyword = "TCP bind";
276 break;
277 case NETWORK_ACL_TCP_LISTEN:
278 keyword = "TCP listen";
279 break;
280 case NETWORK_ACL_TCP_CONNECT:
281 keyword = "TCP connect";
282 break;
283 case NETWORK_ACL_TCP_ACCEPT:
284 keyword = "TCP accept";
285 break;
286 case NETWORK_ACL_RAW_BIND:
287 keyword = "RAW bind";
288 break;
289 case NETWORK_ACL_RAW_CONNECT:
290 keyword = "RAW connect";
291 break;
292 }
293 return keyword;
294 }
295
296 static int AddNetworkEntry(const u8 operation, const u8 record_type, const struct address_group_entry *group, const u32 *min_address, const u32 *max_address, const u16 min_port, const u16 max_port, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
297 {
298 struct acl_info *ptr;
299 struct ip_network_acl_record *acl;
300 struct ip_network_acl_record_with_condition *p;
301 int error = -ENOMEM;
302 const u32 min_ip = ntohl(*min_address), max_ip = ntohl(*max_address); /* using host byte order to allow u32 comparison than memcmp().*/
303 const struct in6_addr *saved_min_address = NULL, *saved_max_address = NULL;
304 if (!domain) return -EINVAL;
305 if (record_type == IP_RECORD_TYPE_IPv6) {
306 if ((saved_min_address = SaveIPv6Address((struct in6_addr *) min_address)) == NULL
307 || (saved_max_address = SaveIPv6Address((struct in6_addr *) max_address)) == NULL) return -ENOMEM;
308 }
309 mutex_lock(&domain_acl_lock);
310 if (!is_delete) {
311 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
312 switch (ptr->type & ~ACL_DELETED) {
313 case TYPE_IP_NETWORK_ACL:
314 if (condition) continue;
315 acl = container_of(ptr, struct ip_network_acl_record, head);
316 break;
317 case TYPE_IP_NETWORK_ACL_WITH_CONDITION:
318 p = container_of(ptr, struct ip_network_acl_record_with_condition, record.head);
319 if (p->condition != condition) continue;
320 acl = &p->record;
321 break;
322 default:
323 continue;
324 }
325 if (acl->operation_type != operation || acl->record_type != record_type || acl->min_port != min_port || max_port != acl->max_port) continue;
326 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
327 if (acl->u.group != group) continue;
328 } else if (record_type == IP_RECORD_TYPE_IPv4) {
329 if (acl->u.ipv4.min != min_ip || max_ip != acl->u.ipv4.max) continue;
330 } else if (record_type == IP_RECORD_TYPE_IPv6) {
331 if (acl->u.ipv6.min != saved_min_address || saved_max_address != acl->u.ipv6.max) continue;
332 }
333 error = AddDomainACL(NULL, ptr);
334 goto out;
335 }
336 /* Not found. Append it to the tail. */
337 if (condition) {
338 if ((p = alloc_element(sizeof(*p))) == NULL) goto out;
339 acl = &p->record;
340 p->condition = condition;
341 acl->head.type = TYPE_IP_NETWORK_ACL_WITH_CONDITION;
342 } else {
343 if ((acl = alloc_element(sizeof(*acl))) == NULL) goto out;
344 acl->head.type = TYPE_IP_NETWORK_ACL;
345 }
346 acl->operation_type = operation;
347 acl->record_type = record_type;
348 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
349 acl->u.group = group;
350 } else if (record_type == IP_RECORD_TYPE_IPv4) {
351 acl->u.ipv4.min = min_ip;
352 acl->u.ipv4.max = max_ip;
353 } else {
354 acl->u.ipv6.min = saved_min_address;
355 acl->u.ipv6.max = saved_max_address;
356 }
357 acl->min_port = min_port;
358 acl->max_port = max_port;
359 error = AddDomainACL(domain, &acl->head);
360 } else {
361 error = -ENOENT;
362 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
363 switch (ptr->type) {
364 case TYPE_IP_NETWORK_ACL:
365 if (condition) continue;
366 acl = container_of(ptr, struct ip_network_acl_record, head);
367 break;
368 case TYPE_IP_NETWORK_ACL_WITH_CONDITION:
369 p = container_of(ptr, struct ip_network_acl_record_with_condition, record.head);
370 if (p->condition != condition) continue;
371 acl = &p->record;
372 break;
373 default:
374 continue;
375 }
376 if (acl->operation_type != operation || acl->record_type != record_type || acl->min_port != min_port || max_port != acl->max_port) continue;
377 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
378 if (acl->u.group != group) continue;
379 } else if (record_type == IP_RECORD_TYPE_IPv4) {
380 if (acl->u.ipv4.min != min_ip || max_ip != acl->u.ipv4.max) continue;
381 } else if (record_type == IP_RECORD_TYPE_IPv6) {
382 if (acl->u.ipv6.min != saved_min_address || saved_max_address != acl->u.ipv6.max) continue;
383 }
384 error = DelDomainACL(ptr);
385 break;
386 }
387 }
388 out: ;
389 mutex_unlock(&domain_acl_lock);
390 return error;
391 }
392
393 static int CheckNetworkEntry(const bool is_ipv6, const u8 operation, const u32 *address, const u16 port)
394 {
395 struct domain_info * const domain = current->domain_info;
396 struct acl_info *ptr;
397 const char *keyword = net_operation2keyword(operation);
398 const u8 profile = current->domain_info->profile;
399 const u8 mode = CheckCCSFlags(CCS_TOMOYO_MAC_FOR_NETWORK);
400 const bool is_enforce = (mode == 3);
401 const u32 ip = ntohl(*address); /* using host byte order to allow u32 comparison than memcmp().*/
402 bool found = 0;
403 if (!mode) return 0;
404 list1_for_each_entry(ptr, &domain->acl_info_list, list) {
405 struct ip_network_acl_record *acl;
406 struct ip_network_acl_record_with_condition *p;
407 const struct condition_list *cond;
408 switch (ptr->type) {
409 default:
410 continue;
411 case TYPE_IP_NETWORK_ACL:
412 acl = container_of(ptr, struct ip_network_acl_record, head);
413 cond = NULL;
414 break;
415 case TYPE_IP_NETWORK_ACL_WITH_CONDITION:
416 p = container_of(ptr, struct ip_network_acl_record_with_condition, record.head);
417 acl = &p->record;
418 cond = p->condition;
419 break;
420 }
421 if (acl->operation_type != operation || port < acl->min_port || acl->max_port < port || !CheckCondition(cond, NULL)) continue;
422 if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
423 if (!AddressMatchesToGroup(is_ipv6, address, acl->u.group)) continue;
424 } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
425 if (is_ipv6 || ip < acl->u.ipv4.min || acl->u.ipv4.max < ip) continue;
426 } else {
427 if (!is_ipv6 || memcmp(acl->u.ipv6.min, address, 16) > 0 || memcmp(address, acl->u.ipv6.max, 16) > 0) continue;
428 }
429 found = 1;
430 break;
431 }
432 AuditNetworkLog(is_ipv6, keyword, address, port, found, profile, mode);
433 if (found) return 0;
434 if (TomoyoVerboseMode()) {
435 if (is_ipv6) {
436 char buf[64];
437 print_ipv6(buf, sizeof(buf), (const struct in6_addr *) address);
438 printk("TOMOYO-%s: %s to %s %u denied for %s\n", GetMSG(is_enforce), keyword, buf, port, GetLastName(domain));
439 } else {
440 printk("TOMOYO-%s: %s to %u.%u.%u.%u %u denied for %s\n", GetMSG(is_enforce), keyword, HIPQUAD(ip), port, GetLastName(domain));
441 }
442 }
443 if (is_enforce) {
444 if (is_ipv6) {
445 char buf[64];
446 print_ipv6(buf, sizeof(buf), (const struct in6_addr *) address);
447 return CheckSupervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s %s %u\n", domain->domainname->name, keyword, buf, port);
448 }
449 return CheckSupervisor("%s\n" KEYWORD_ALLOW_NETWORK "%s %u.%u.%u.%u %u\n", domain->domainname->name, keyword, HIPQUAD(ip), port);
450 }
451 else if (mode == 1 && CheckDomainQuota(domain)) AddNetworkEntry(operation, is_ipv6 ? IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4, NULL, address, address, port, port, domain, NULL, 0);
452 return 0;
453 }
454
455 int AddNetworkPolicy(char *data, struct domain_info *domain, const struct condition_list *condition, const bool is_delete)
456 {
457 u8 sock_type, operation, record_type;
458 u16 min_address[8], max_address[8];
459 struct address_group_entry *group = NULL;
460 u16 min_port, max_port;
461 u8 count;
462 char *cp1 = NULL, *cp2 = NULL;
463 if ((cp1 = strchr(data, ' ')) == NULL) goto out; cp1++;
464 if (strncmp(data, "TCP ", 4) == 0) sock_type = SOCK_STREAM;
465 else if (strncmp(data, "UDP ", 4) == 0) sock_type = SOCK_DGRAM;
466 else if (strncmp(data, "RAW ", 4) == 0) sock_type = SOCK_RAW;
467 else goto out;
468 if ((cp2 = strchr(cp1, ' ')) == NULL) goto out; cp2++;
469 if (strncmp(cp1, "bind ", 5) == 0) {
470 operation = (sock_type == SOCK_STREAM) ? NETWORK_ACL_TCP_BIND : (sock_type == SOCK_DGRAM) ? NETWORK_ACL_UDP_BIND : NETWORK_ACL_RAW_BIND;
471 } else if (strncmp(cp1, "connect ", 8) == 0) {
472 operation = (sock_type == SOCK_STREAM) ? NETWORK_ACL_TCP_CONNECT : (sock_type == SOCK_DGRAM) ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT;
473 } else if (sock_type == SOCK_STREAM && strncmp(cp1, "listen ", 7) == 0) {
474 operation = NETWORK_ACL_TCP_LISTEN;
475 } else if (sock_type == SOCK_STREAM && strncmp(cp1, "accept ", 7) == 0) {
476 operation = NETWORK_ACL_TCP_ACCEPT;
477 } else {
478 goto out;
479 }
480 if ((cp1 = strchr(cp2, ' ')) == NULL) goto out; *cp1++ = '\0';
481 if ((count = sscanf(cp2, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
482 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
483 &min_address[4], &min_address[5], &min_address[6], &min_address[7],
484 &max_address[0], &max_address[1], &max_address[2], &max_address[3],
485 &max_address[4], &max_address[5], &max_address[6], &max_address[7])) == 8 || count == 16) {
486 u8 i;
487 for (i = 0; i < 8; i++) {
488 min_address[i] = htons(min_address[i]);
489 max_address[i] = htons(max_address[i]);
490 }
491 if (count == 8) memmove(max_address, min_address, sizeof(min_address));
492 record_type = IP_RECORD_TYPE_IPv6;
493 } else if ((count = sscanf(cp2, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
494 &min_address[0], &min_address[1], &min_address[2], &min_address[3],
495 &max_address[0], &max_address[1], &max_address[2], &max_address[3])) == 4 || count == 8) {
496 u32 ip = htonl((((u8) min_address[0]) << 24) + (((u8) min_address[1]) << 16) + (((u8) min_address[2]) << 8) + (u8) min_address[3]);
497 * (u32 *) min_address = ip;
498 if (count == 8) ip = htonl((((u8) max_address[0]) << 24) + (((u8) max_address[1]) << 16) + (((u8) max_address[2]) << 8) + (u8) max_address[3]);
499 * (u32 *) max_address = ip;
500 record_type = IP_RECORD_TYPE_IPv4;
501 } else if (*cp2 == '@') {
502 if ((group = FindOrAssignNewAddressGroup(cp2 + 1)) == NULL) return -ENOMEM;
503 record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
504 } else {
505 goto out;
506 }
507 if (strchr(cp1, ' ')) goto out;
508 if ((count = sscanf(cp1, "%hu-%hu", &min_port, &max_port)) == 1 || count == 2) {
509 if (count == 1) max_port = min_port;
510 return AddNetworkEntry(operation, record_type, group, (u32 *) min_address, (u32 *) max_address, min_port, max_port, domain, condition, is_delete);
511 }
512 out: ;
513 return -EINVAL;
514 }
515
516 int CheckNetworkListenACL(const _Bool is_ipv6, const u8 *address, const u16 port)
517 {
518 return CheckNetworkEntry(is_ipv6, NETWORK_ACL_TCP_LISTEN, (const u32 *) address, ntohs(port));
519 }
520
521 int CheckNetworkConnectACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
522 {
523 return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_CONNECT : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT), (const u32 *) address, ntohs(port));
524 }
525
526 int CheckNetworkBindACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
527 {
528 return CheckNetworkEntry(is_ipv6, sock_type == SOCK_STREAM ? NETWORK_ACL_TCP_BIND : (sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_BIND : NETWORK_ACL_RAW_BIND), (const u32 *) address, ntohs(port));
529 }
530
531 int CheckNetworkAcceptACL(const _Bool is_ipv6, const u8 *address, const u16 port)
532 {
533 int retval;
534 current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
535 retval = CheckNetworkEntry(is_ipv6, NETWORK_ACL_TCP_ACCEPT, (const u32 *) address, ntohs(port));
536 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
537 return retval;
538 }
539
540 int CheckNetworkSendMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
541 {
542 return CheckNetworkEntry(is_ipv6, sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT, (const u32 *) address, ntohs(port));
543 }
544
545 int CheckNetworkRecvMsgACL(const _Bool is_ipv6, const int sock_type, const u8 *address, const u16 port)
546 {
547 int retval;
548 current->tomoyo_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
549 retval = CheckNetworkEntry(is_ipv6, sock_type == SOCK_DGRAM ? NETWORK_ACL_UDP_CONNECT : NETWORK_ACL_RAW_CONNECT, (const u32 *) address, ntohs(port));
550 current->tomoyo_flags &= ~CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
551 return retval;
552 }
553
554 /***** TOMOYO Linux end. *****/

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26