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

Subversion リポジトリの参照

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1286 by kumaneko, Thu Jun 12 01:38:25 2008 UTC revision 1782 by kumaneko, Tue Nov 4 08:08:46 2008 UTC
# Line 5  Line 5 
5   *   *
6   * Copyright (C) 2005-2008  NTT DATA CORPORATION   * Copyright (C) 2005-2008  NTT DATA CORPORATION
7   *   *
8   * Version: 1.6.2-rc   2008/06/12   * Version: 1.6.5-pre   2008/11/04
9   *   *
10   * This file is applicable to both 2.4.30 and 2.6.11 and later.   * This file is applicable to both 2.4.30 and 2.6.11 and later.
11   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 23  Line 23 
23  /**  /**
24   * audit_network_log - Audit network log.   * audit_network_log - Audit network log.
25   *   *
26   * @is_ipv6:    True if @address is an IPv6 address.   * @r:          Pointer to "struct ccs_request_info".
27   * @operation:  The name of operation.   * @operation:  The name of operation.
28   * @address:    An IPv4 or IPv6 address.   * @address:    An IPv4 or IPv6 address.
29   * @port:       Port number.   * @port:       Port number.
30   * @is_granted: True if this is a granted log.   * @is_granted: True if this is a granted log.
  * @profile:    Profile number used.  
  * @mode:       Access control mode used.  
31   *   *
32   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
33   */   */
34  static int audit_network_log(const bool is_ipv6, const char *operation,  static int audit_network_log(struct ccs_request_info *r, const char *operation,
35                               const char *address, const u16 port,                               const char *address, const u16 port,
36                               const bool is_granted,                               const bool is_granted)
                              const u8 profile, const u8 mode)  
37  {  {
38          char *buf;          return ccs_write_audit_log(is_granted, r, KEYWORD_ALLOW_NETWORK
39          int len = 256;                                     "%s %s %u\n", operation, address, port);
         int len2;  
         if (ccs_can_save_audit_log(is_granted) < 0)  
                 return -ENOMEM;  
         buf = ccs_init_audit_log(&len, profile, mode, NULL);  
         if (!buf)  
                 return -ENOMEM;  
         len2 = strlen(buf);  
         snprintf(buf + len2, len - len2 - 1, KEYWORD_ALLOW_NETWORK "%s %s %u\n",  
                  operation, address, port);  
         return ccs_write_audit_log(buf, is_granted);  
40  }  }
41    
42  /**  /**
# Line 65  static const struct in6_addr *save_ipv6_ Line 52  static const struct in6_addr *save_ipv6_
52  {  {
53          static const u8 block_size = 16;          static const u8 block_size = 16;
54          struct addr_list {          struct addr_list {
55                  struct in6_addr addr[block_size];                  /* Workaround for gcc 4.3's bug. */
56                    struct in6_addr addr[16]; /* = block_size */
57                  struct list1_head list;                  struct list1_head list;
58                  u32 in_use_count;                  u32 in_use_count;
59          };          };
# Line 199  static int update_address_group_entry(co Line 187  static int update_address_group_entry(co
187  }  }
188    
189  /**  /**
190     * parse_ip_address - Parse an IP address.
191     *
192     * @address: String to parse.
193     * @min:     Pointer to store min address.
194     * @max:     Pointer to store max address.
195     *
196     * Returns 2 if @address is an IPv6, 1 if @address is an IPv4, 0 otherwise.
197     */
198    static int parse_ip_address(char *address, u16 *min, u16 *max)
199    {
200            int count = sscanf(address, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"
201                               "-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",
202                               &min[0], &min[1], &min[2], &min[3],
203                               &min[4], &min[5], &min[6], &min[7],
204                               &max[0], &max[1], &max[2], &max[3],
205                               &max[4], &max[5], &max[6], &max[7]);
206            if (count == 8 || count == 16) {
207                    u8 i;
208                    if (count == 8)
209                            memmove(max, min, sizeof(u16) * 8);
210                    for (i = 0; i < 8; i++) {
211                            min[i] = htons(min[i]);
212                            max[i] = htons(max[i]);
213                    }
214                    return 2;
215            }
216            count = sscanf(address, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
217                           &min[0], &min[1], &min[2], &min[3],
218                           &max[0], &max[1], &max[2], &max[3]);
219            if (count == 4 || count == 8) {
220                    u32 ip = htonl((((u8) min[0]) << 24) + (((u8) min[1]) << 16)
221                                   + (((u8) min[2]) << 8) + (u8) min[3]);
222                    memmove(min, &ip, sizeof(ip));
223                    if (count == 8)
224                            ip = htonl((((u8) max[0]) << 24) + (((u8) max[1]) << 16)
225                                       + (((u8) max[2]) << 8) + (u8) max[3]);
226                    memmove(max, &ip, sizeof(ip));
227                    return 1;
228            }
229            return 0;
230    }
231    
232    /**
233   * ccs_write_address_group_policy - Write "struct address_group_entry" list.   * ccs_write_address_group_policy - Write "struct address_group_entry" list.
234   *   *
235   * @data:      String to parse.   * @data:      String to parse.
# Line 208  static int update_address_group_entry(co Line 239  static int update_address_group_entry(co
239   */   */
240  int ccs_write_address_group_policy(char *data, const bool is_delete)  int ccs_write_address_group_policy(char *data, const bool is_delete)
241  {  {
         u8 count;  
242          bool is_ipv6;          bool is_ipv6;
243          u16 min_address[8];          u16 min_address[8];
244          u16 max_address[8];          u16 max_address[8];
# Line 216  int ccs_write_address_group_policy(char Line 246  int ccs_write_address_group_policy(char
246          if (!cp)          if (!cp)
247                  return -EINVAL;                  return -EINVAL;
248          *cp++ = '\0';          *cp++ = '\0';
249          count = sscanf(cp, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"          switch (parse_ip_address(cp, min_address, max_address)) {
250                         "-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",          case 2:
                        &min_address[0], &min_address[1],  
                        &min_address[2], &min_address[3],  
                        &min_address[4], &min_address[5],  
                        &min_address[6], &min_address[7],  
                        &max_address[0], &max_address[1],  
                        &max_address[2], &max_address[3],  
                        &max_address[4], &max_address[5],  
                        &max_address[6], &max_address[7]);  
         if (count == 8 || count == 16) {  
                 u8 i;  
                 for (i = 0; i < 8; i++) {  
                         min_address[i] = htons(min_address[i]);  
                         max_address[i] = htons(max_address[i]);  
                 }  
                 if (count == 8)  
                         memmove(max_address, min_address, sizeof(min_address));  
251                  is_ipv6 = true;                  is_ipv6 = true;
252                  goto ok;                  break;
253          }          case 1:
         count = sscanf(cp, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",  
                        &min_address[0], &min_address[1],  
                        &min_address[2], &min_address[3],  
                        &max_address[0], &max_address[1],  
                        &max_address[2], &max_address[3]);  
         if (count == 4 || count == 8) {  
                 u32 ip = ((((u8) min_address[0]) << 24)  
                           + (((u8) min_address[1]) << 16)  
                           + (((u8) min_address[2]) << 8)  
                           + (u8) min_address[3]);  
                 *(u32 *) min_address = ip;  
                 if (count == 8)  
                         ip = ((((u8) max_address[0]) << 24)  
                               + (((u8) max_address[1]) << 16)  
                               + (((u8) max_address[2]) << 8)  
                               + (u8) max_address[3]);  
                 *(u32 *) max_address = ip;  
254                  is_ipv6 = false;                  is_ipv6 = false;
255                  goto ok;                  break;
256            default:
257                    return -EINVAL;
258          }          }
         return -EINVAL;  
  ok:  
259          return update_address_group_entry(data, is_ipv6,          return update_address_group_entry(data, is_ipv6,
260                                            min_address, max_address, is_delete);                                            min_address, max_address, is_delete);
261  }  }
# Line 470  static int update_network_entry(const u8 Line 467  static int update_network_entry(const u8
467                                  const struct condition_list *condition,                                  const struct condition_list *condition,
468                                  const bool is_delete)                                  const bool is_delete)
469  {  {
470            static DEFINE_MUTEX(lock);
471          struct acl_info *ptr;          struct acl_info *ptr;
472          struct ip_network_acl_record *acl;          struct ip_network_acl_record *acl;
473          int error = -ENOMEM;          int error = -ENOMEM;
# Line 487  static int update_network_entry(const u8 Line 485  static int update_network_entry(const u8
485          if (!saved_min_address || !saved_max_address)          if (!saved_min_address || !saved_max_address)
486                  return -ENOMEM;                  return -ENOMEM;
487   not_ipv6:   not_ipv6:
488          mutex_lock(&domain_acl_lock);          mutex_lock(&lock);
489          if (is_delete)          if (is_delete)
490                  goto delete;                  goto delete;
491          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          list1_for_each_entry(ptr, &domain->acl_info_list, list) {
# Line 562  static int update_network_entry(const u8 Line 560  static int update_network_entry(const u8
560                  break;                  break;
561          }          }
562   out:   out:
563          mutex_unlock(&domain_acl_lock);          mutex_unlock(&lock);
564          return error;          return error;
565  }  }
566    
# Line 579  static int update_network_entry(const u8 Line 577  static int update_network_entry(const u8
577  static int check_network_entry(const bool is_ipv6, const u8 operation,  static int check_network_entry(const bool is_ipv6, const u8 operation,
578                                 const u32 *address, const u16 port)                                 const u32 *address, const u16 port)
579  {  {
580          struct domain_info * const domain = current->domain_info;          struct ccs_request_info r;
581          struct acl_info *ptr;          struct acl_info *ptr;
582          const char *keyword = ccs_net2keyword(operation);          const char *keyword = ccs_net2keyword(operation);
583          const u8 profile = current->domain_info->profile;          bool is_enforce;
         const u8 mode = ccs_check_flags(CCS_TOMOYO_MAC_FOR_NETWORK);  
         const bool is_enforce = (mode == 3);  
584          /* using host byte order to allow u32 comparison than memcmp().*/          /* using host byte order to allow u32 comparison than memcmp().*/
585          const u32 ip = ntohl(*address);          const u32 ip = ntohl(*address);
586          bool found = false;          bool found = false;
587          char buf[64];          char buf[64];
588          if (!mode)          if (!ccs_can_sleep())
589                  return 0;                  return 0;
590          list1_for_each_entry(ptr, &domain->acl_info_list, list) {          ccs_init_request_info(&r, NULL, CCS_TOMOYO_MAC_FOR_NETWORK);
591            is_enforce = (r.mode == 3);
592            if (!r.mode)
593                    return 0;
594    retry:
595            list1_for_each_entry(ptr, &r.domain->acl_info_list, list) {
596                  struct ip_network_acl_record *acl;                  struct ip_network_acl_record *acl;
597                  if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)                  if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
598                          continue;                          continue;
599                  acl = container_of(ptr, struct ip_network_acl_record, head);                  acl = container_of(ptr, struct ip_network_acl_record, head);
600                  if (acl->operation_type != operation || port < acl->min_port ||                  if (acl->operation_type != operation || port < acl->min_port ||
601                      acl->max_port < port || !ccs_check_condition(ptr, NULL))                      acl->max_port < port || !ccs_check_condition(&r, ptr))
602                          continue;                          continue;
603                  if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {                  if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
604                          if (!address_matches_to_group(is_ipv6, address,                          if (!address_matches_to_group(is_ipv6, address,
# Line 613  static int check_network_entry(const boo Line 614  static int check_network_entry(const boo
614                              memcmp(address, acl->u.ipv6.max, 16) > 0)                              memcmp(address, acl->u.ipv6.max, 16) > 0)
615                                  continue;                                  continue;
616                  }                  }
617                  ccs_update_condition(ptr);                  r.cond = ccs_get_condition_part(ptr);
618                  found = true;                  found = true;
619                  break;                  break;
620          }          }
# Line 623  static int check_network_entry(const boo Line 624  static int check_network_entry(const boo
624                                 (const struct in6_addr *) address);                                 (const struct in6_addr *) address);
625          else          else
626                  snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));                  snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));
627          audit_network_log(is_ipv6, keyword, buf, port, found, profile, mode);          audit_network_log(&r, keyword, buf, port, found);
628          if (found)          if (found)
629                  return 0;                  return 0;
630          if (ccs_verbose_mode())          if (ccs_verbose_mode(r.domain))
631                  printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",                  printk(KERN_WARNING "TOMOYO-%s: %s to %s %u denied for %s\n",
632                         ccs_get_msg(is_enforce), keyword, buf, port,                         ccs_get_msg(is_enforce), keyword, buf, port,
633                         ccs_get_last_name(domain));                         ccs_get_last_name(r.domain));
634          if (is_enforce)          if (is_enforce) {
635                  return ccs_check_supervisor(NULL, KEYWORD_ALLOW_NETWORK "%s "                  int error = ccs_check_supervisor(&r, KEYWORD_ALLOW_NETWORK
636                                              "%s %u\n", keyword, buf, port);                                                   "%s %s %u\n", keyword, buf,
637          if (mode == 1 && ccs_check_domain_quota(domain))                                                   port);
638                    if (error == 1)
639                            goto retry;
640                    return error;
641            }
642            if (r.mode == 1 && ccs_check_domain_quota(r.domain))
643                  update_network_entry(operation, is_ipv6 ?                  update_network_entry(operation, is_ipv6 ?
644                                       IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4,                                       IP_RECORD_TYPE_IPv6 : IP_RECORD_TYPE_IPv4,
645                                       NULL, address, address, port, port, domain,                                       NULL, address, address, port, port,
646                                       NULL, 0);                                       r.domain, NULL, 0);
647          return 0;          return 0;
648  }  }
649    
# Line 713  int ccs_write_network_policy(char *data, Line 719  int ccs_write_network_policy(char *data,
719          if (!cp1)          if (!cp1)
720                  goto out;                  goto out;
721          *cp1++ = '\0';          *cp1++ = '\0';
722          count = sscanf(cp2, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx"          switch (parse_ip_address(cp2, min_address, max_address)) {
723                         "-%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx",          case 2:
                        &min_address[0], &min_address[1],  
                        &min_address[2], &min_address[3],  
                        &min_address[4], &min_address[5],  
                        &min_address[6], &min_address[7],  
                        &max_address[0], &max_address[1],  
                        &max_address[2], &max_address[3],  
                        &max_address[4], &max_address[5],  
                        &max_address[6], &max_address[7]);  
         if (count == 8 || count == 16) {  
                 u8 i;  
                 for (i = 0; i < 8; i++) {  
                         min_address[i] = htons(min_address[i]);  
                         max_address[i] = htons(max_address[i]);  
                 }  
                 if (count == 8)  
                         memmove(max_address, min_address, sizeof(min_address));  
724                  record_type = IP_RECORD_TYPE_IPv6;                  record_type = IP_RECORD_TYPE_IPv6;
725                  goto ok;                  break;
726          }          case 1:
         count = sscanf(cp2, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",  
                        &min_address[0], &min_address[1],  
                        &min_address[2], &min_address[3],  
                        &max_address[0], &max_address[1],  
                        &max_address[2], &max_address[3]);  
         if (count == 4 || count == 8) {  
                 u32 ip = htonl((((u8) min_address[0]) << 24)  
                                + (((u8) min_address[1]) << 16)  
                                + (((u8) min_address[2]) << 8)  
                                + (u8) min_address[3]);  
                 *(u32 *) min_address = ip;  
                 if (count == 8)  
                         ip = htonl((((u8) max_address[0]) << 24)  
                                    + (((u8) max_address[1]) << 16)  
                                    + (((u8) max_address[2]) << 8)  
                                    + (u8) max_address[3]);  
                 *(u32 *) max_address = ip;  
727                  record_type = IP_RECORD_TYPE_IPv4;                  record_type = IP_RECORD_TYPE_IPv4;
728                  goto ok;                  break;
729          }          default:
730          if (*cp2 == '@') {                  if (*cp2 != '@')
731                            goto out;
732                  group = find_or_assign_new_address_group(cp2 + 1);                  group = find_or_assign_new_address_group(cp2 + 1);
733                  if (!group)                  if (!group)
734                          return -ENOMEM;                          return -ENOMEM;
735                  record_type = IP_RECORD_TYPE_ADDRESS_GROUP;                  record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
736                  goto ok;                  break;
737          }          }
  out:  
         return -EINVAL;  
  ok:  
738          if (strchr(cp1, ' '))          if (strchr(cp1, ' '))
739                  goto out;                  goto out;
740          count = sscanf(cp1, "%hu-%hu", &min_port, &max_port);          count = sscanf(cp1, "%hu-%hu", &min_port, &max_port);
# Line 775  int ccs_write_network_policy(char *data, Line 746  int ccs_write_network_policy(char *data,
746                                      (u32 *) min_address, (u32 *) max_address,                                      (u32 *) min_address, (u32 *) max_address,
747                                      min_port, max_port, domain, condition,                                      min_port, max_port, domain, condition,
748                                      is_delete);                                      is_delete);
749     out:
750            return -EINVAL;
751  }  }
752    
753  /**  /**

Legend:
Removed from v.1286  
changed lines
  Added in v.1782

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