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

Subversion リポジトリの参照

Diff of /branches/ccs-patch/security/ccsecurity/network.c

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

revision 2860 by kumaneko, Thu Aug 6 07:57:13 2009 UTC revision 2863 by kumaneko, Fri Aug 7 06:27:45 2009 UTC
# Line 18  Line 18 
18  #include <net/ipv6.h>  #include <net/ipv6.h>
19  #include <net/udp.h>  #include <net/udp.h>
20  #include "internal.h"  #include "internal.h"
 #include <linux/ccsecurity.h>  
21    
22  /* Index numbers for Network Controls. */  /* Index numbers for Network Controls. */
23  enum ccs_network_acl_index {  enum ccs_network_acl_index {
# Line 447  const char *ccs_net2keyword(const u8 ope Line 446  const char *ccs_net2keyword(const u8 ope
446   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
447   */   */
448  static int ccs_update_network_entry(const u8 operation, const u8 record_type,  static int ccs_update_network_entry(const u8 operation, const u8 record_type,
449                                      const char *group_name,                                      const char *address_group_name,
450                                        const char *port_group_name,
451                                      const u32 *min_address,                                      const u32 *min_address,
452                                      const u32 *max_address,                                      const u32 *max_address,
453                                      const u16 min_port, const u16 max_port,                                      const u16 min_port, const u16 max_port,
# Line 455  static int ccs_update_network_entry(cons Line 455  static int ccs_update_network_entry(cons
455                                      struct ccs_condition *condition,                                      struct ccs_condition *condition,
456                                      const bool is_delete)                                      const bool is_delete)
457  {  {
         struct ccs_ip_network_acl_record *entry = NULL;  
458          struct ccs_acl_info *ptr;          struct ccs_acl_info *ptr;
459            struct ccs_ip_network_acl_record e;
460            struct ccs_ip_network_acl_record *entry = NULL;
461          int error = is_delete ? -ENOENT : -ENOMEM;          int error = is_delete ? -ENOENT : -ENOMEM;
462          /* using host byte order to allow u32 comparison than memcmp().*/          memset(&e, 0, sizeof(e));
463          const u32 min_ip = ntohl(*min_address);          e.head.type = TYPE_IP_NETWORK_ACL;
464          const u32 max_ip = ntohl(*max_address);          e.head.cond = condition;
         const struct in6_addr *saved_min_address = NULL;  
         const struct in6_addr *saved_max_address = NULL;  
         struct ccs_address_group_entry *group = NULL;  
465          if (!domain)          if (!domain)
466                  return -EINVAL;                  return -EINVAL;
467          if (group_name) {          if (address_group_name) {
468                  group = ccs_get_address_group(group_name);                  e.address.group = ccs_get_address_group(address_group_name);
469                  if (!group)                  if (!e.address.group)
470                          return -ENOMEM;                          return -ENOMEM;
471          } else if (record_type == IP_RECORD_TYPE_IPv6) {          } else if (record_type == IP_RECORD_TYPE_IPv6) {
472                  saved_min_address = ccs_get_ipv6_address((struct in6_addr *)                  e.address.ipv6.min = ccs_get_ipv6_address((struct in6_addr *)
473                                                           min_address);                                                            min_address);
474                  saved_max_address = ccs_get_ipv6_address((struct in6_addr *)                  e.address.ipv6.max = ccs_get_ipv6_address((struct in6_addr *)
475                                                           max_address);                                                            max_address);
476                  if (!saved_min_address || !saved_max_address)                  if (!e.address.ipv6.min || !e.address.ipv6.max)
477                          goto out;                          goto out;
478            } else {
479                    /* use host byte order to allow u32 comparison than memcmp().*/
480                    e.address.ipv4.min = ntohl(*min_address);
481                    e.address.ipv4.max = ntohl(*max_address);
482            }
483            if (port_group_name) {
484                    if (!ccs_check_and_save_number(port_group_name,
485                                                   &e.port_is_group, &e.port))
486                        goto out;
487            } else {
488                    e.port.value.min = min_port;
489                    e.port.value.max = max_port;
490          }          }
491          if (is_delete)          if (is_delete)
492                  goto delete;                  goto delete;
# Line 489  static int ccs_update_network_entry(cons Line 499  static int ccs_update_network_entry(cons
499                  if (ptr->cond != condition)                  if (ptr->cond != condition)
500                          continue;                          continue;
501                  acl = container_of(ptr, struct ccs_ip_network_acl_record, head);                  acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
502                  if (acl->operation_type != operation ||                  if (memcmp(acl, &e, sizeof(e)))
                     acl->record_type != record_type ||  
                     acl->min_port != min_port || max_port != acl->max_port)  
503                          continue;                          continue;
                 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {  
                         if (acl->u.group != group)  
                                 continue;  
                 } else if (record_type == IP_RECORD_TYPE_IPv4) {  
                         if (acl->u.ipv4.min != min_ip ||  
                             max_ip != acl->u.ipv4.max)  
                                 continue;  
                 } else if (record_type == IP_RECORD_TYPE_IPv6) {  
                         if (acl->u.ipv6.min != saved_min_address ||  
                             saved_max_address != acl->u.ipv6.max)  
                                 continue;  
                 }  
504                  error = ccs_add_domain_acl(NULL, ptr);                  error = ccs_add_domain_acl(NULL, ptr);
505                  break;                  break;
506          }          }
507          if (error && ccs_memory_ok(entry, sizeof(*entry))) {          if (error && ccs_memory_ok(entry, sizeof(*entry))) {
508                  entry->head.type = TYPE_IP_NETWORK_ACL;                  memmove(entry, &e, sizeof(e));
509                  entry->head.cond = condition;                  memset(&e, 0, sizeof(e));
                 entry->operation_type = operation;  
                 entry->record_type = record_type;  
                 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {  
                         entry->u.group = group;  
                         group = NULL;  
                 } else if (record_type == IP_RECORD_TYPE_IPv4) {  
                         entry->u.ipv4.min = min_ip;  
                         entry->u.ipv4.max = max_ip;  
                 } else {  
                         entry->u.ipv6.min = saved_min_address;  
                         saved_min_address = NULL;  
                         entry->u.ipv6.max = saved_max_address;  
                         saved_max_address = NULL;  
                 }  
                 entry->min_port = min_port;  
                 entry->max_port = max_port;  
510                  error = ccs_add_domain_acl(domain, &entry->head);                  error = ccs_add_domain_acl(domain, &entry->head);
511                  entry = NULL;                  entry = NULL;
512          }          }
# Line 541  static int ccs_update_network_entry(cons Line 521  static int ccs_update_network_entry(cons
521                  if (ptr->cond != condition)                  if (ptr->cond != condition)
522                          continue;                          continue;
523                  acl = container_of(ptr, struct ccs_ip_network_acl_record, head);                  acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
524                  if (acl->operation_type != operation ||                  if (memcmp(acl, &e, sizeof(e)))
                     acl->record_type != record_type ||  
                     acl->min_port != min_port || max_port != acl->max_port)  
525                          continue;                          continue;
                 if (record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {  
                         if (acl->u.group != group)  
                                 continue;  
                 } else if (record_type == IP_RECORD_TYPE_IPv4) {  
                         if (acl->u.ipv4.min != min_ip ||  
                             max_ip != acl->u.ipv4.max)  
                                 continue;  
                 } else if (record_type == IP_RECORD_TYPE_IPv6) {  
                         if (acl->u.ipv6.min != saved_min_address ||  
                             saved_max_address != acl->u.ipv6.max)  
                                 continue;  
                 }  
526                  error = ccs_del_domain_acl(ptr);                  error = ccs_del_domain_acl(ptr);
527                  break;                  break;
528          }          }
529          mutex_unlock(&ccs_policy_lock);          mutex_unlock(&ccs_policy_lock);
530   out:   out:
531          ccs_put_ipv6_address(saved_min_address);          if (address_group_name)
532          ccs_put_ipv6_address(saved_max_address);                  ccs_put_address_group(e.address.group);
533          ccs_put_address_group(group);          else if (record_type == IP_RECORD_TYPE_IPv6) {
534                    ccs_put_ipv6_address(e.address.ipv6.min);
535                    ccs_put_ipv6_address(e.address.ipv6.max);
536            }
537            if (port_group_name)
538                    ccs_put_number_group(e.port.group);
539          kfree(entry);          kfree(entry);
540          return error;          return error;
541  }  }
# Line 605  static int ccs_check_network_entry2(cons Line 576  static int ccs_check_network_entry2(cons
576                  if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)                  if (ccs_acl_type2(ptr) != TYPE_IP_NETWORK_ACL)
577                          continue;                          continue;
578                  acl = container_of(ptr, struct ccs_ip_network_acl_record, head);                  acl = container_of(ptr, struct ccs_ip_network_acl_record, head);
579                  if (acl->operation_type != operation || port < acl->min_port ||                  if (acl->operation_type != operation)
580                      acl->max_port < port || !ccs_check_condition(&r, ptr))                          continue;
581                    if (acl->port_is_group) {
582                            if (!ccs_number_matches_group(port, port,
583                                                          acl->port.group))
584                                    continue;
585                    } else {
586                            if (port < acl->port.value.min ||
587                                acl->port.value.max < port)
588                                    continue;
589                    }
590                    if (!ccs_check_condition(&r, ptr))
591                          continue;                          continue;
592                  if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {                  if (acl->record_type == IP_RECORD_TYPE_ADDRESS_GROUP) {
593                          if (!ccs_address_matches_group(is_ipv6, address,                          if (!ccs_address_matches_group(is_ipv6, address,
594                                                         acl->u.group))                                                         acl->address.group))
595                                  continue;                                  continue;
596                  } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {                  } else if (acl->record_type == IP_RECORD_TYPE_IPv4) {
597                          if (is_ipv6 ||                          if (is_ipv6 ||
598                              ip < acl->u.ipv4.min || acl->u.ipv4.max < ip)                              ip < acl->address.ipv4.min ||
599                                acl->address.ipv4.max < ip)
600                                  continue;                                  continue;
601                  } else {                  } else {
602                          if (!is_ipv6 ||                          if (!is_ipv6 ||
603                              memcmp(acl->u.ipv6.min, address, 16) > 0 ||                              memcmp(acl->address.ipv6.min, address, 16) > 0 ||
604                              memcmp(address, acl->u.ipv6.max, 16) > 0)                              memcmp(address, acl->address.ipv6.max, 16) > 0)
605                                  continue;                                  continue;
606                  }                  }
607                  r.cond = ptr->cond;                  r.cond = ptr->cond;
# Line 647  static int ccs_check_network_entry2(cons Line 629  static int ccs_check_network_entry2(cons
629                  ccs_update_network_entry(operation, is_ipv6 ?                  ccs_update_network_entry(operation, is_ipv6 ?
630                                           IP_RECORD_TYPE_IPv6 :                                           IP_RECORD_TYPE_IPv6 :
631                                           IP_RECORD_TYPE_IPv4,                                           IP_RECORD_TYPE_IPv4,
632                                           NULL, address, address, port, port,                                           NULL, NULL, address, address, port,
633                                           r.domain, cond, false);                                           port, r.domain, cond, false);
634                  ccs_put_condition(cond);                  ccs_put_condition(cond);
635          }          }
636          return 0;          return 0;
# Line 694  int ccs_write_network_policy(char *data, Line 676  int ccs_write_network_policy(char *data,
676          u8 record_type;          u8 record_type;
677          u16 min_address[8];          u16 min_address[8];
678          u16 max_address[8];          u16 max_address[8];
679          const char *group_name = NULL;          const char *address_group_name = NULL;
680            const char *port_group_name = NULL;
681          u16 min_port;          u16 min_port;
682          u16 max_port;          u16 max_port;
         u8 count;  
683          if (!ccs_tokenize(data, w, sizeof(w)) || !w[3][0])          if (!ccs_tokenize(data, w, sizeof(w)) || !w[3][0])
684                  return -EINVAL;                  return -EINVAL;
685          if (!strcmp(w[0], "TCP"))          if (!strcmp(w[0], "TCP"))
# Line 746  int ccs_write_network_policy(char *data, Line 728  int ccs_write_network_policy(char *data,
728          default:          default:
729                  if (w[2][0] != '@')                  if (w[2][0] != '@')
730                          goto out;                          goto out;
731                  group_name = w[2] + 1;                  address_group_name = w[2] + 1;
732                  record_type = IP_RECORD_TYPE_ADDRESS_GROUP;                  record_type = IP_RECORD_TYPE_ADDRESS_GROUP;
733                  break;                  break;
734          }          }
735          count = sscanf(w[3], "%hu-%hu", &min_port, &max_port);          switch (sscanf(w[3], "%hu-%hu", &min_port, &max_port)) {
736          if (count != 1 && count != 2)          case 2:
737                  goto out;                  break;
738          if (count == 1)          case 1:
739                  max_port = min_port;                  max_port = min_port;
740          return ccs_update_network_entry(operation, record_type, group_name,                  break;
741            default:
742                    if (w[3][0] != '@')
743                            goto out;
744                    port_group_name = w[3];
745                    break;
746            }
747            return ccs_update_network_entry(operation, record_type,
748                                            address_group_name, port_group_name,
749                                          (u32 *) min_address,                                          (u32 *) min_address,
750                                          (u32 *) max_address,                                          (u32 *) max_address,
751                                          min_port, max_port, domain, condition,                                          min_port, max_port, domain, condition,

Legend:
Removed from v.2860  
changed lines
  Added in v.2863

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