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

Subversion リポジトリの参照

Annotation of /trunk/1.8.x/ccs-patch/security/ccsecurity/network.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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