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

Subversion リポジトリの参照

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

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

trunk/1.7.x/ccs-patch/security/ccsecurity/network.c revision 3502 by kumaneko, Mon Mar 8 08:44:55 2010 UTC branches/ccs-patch/security/ccsecurity/network.c revision 3695 by kumaneko, Mon May 24 04:35:02 2010 UTC
# Line 3  Line 3 
3   *   *
4   * Copyright (C) 2005-2010  NTT DATA CORPORATION   * Copyright (C) 2005-2010  NTT DATA CORPORATION
5   *   *
6   * Version: 1.7.2-pre   2010/03/08   * Version: 1.7.2   2010/04/01
7   *   *
8   * 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.
9   * See README.ccs for ChangeLog.   * See README.ccs for ChangeLog.
# Line 36  static int ccs_audit_network_log(struct Line 36  static int ccs_audit_network_log(struct
36  {  {
37          if (!is_granted)          if (!is_granted)
38                  ccs_warn_log(r, "%s %s %u", operation, address, port);                  ccs_warn_log(r, "%s %s %u", operation, address, port);
39          return ccs_write_audit_log(is_granted, r, CCS_KEYWORD_ALLOW_NETWORK          return ccs_write_log(is_granted, r, CCS_KEYWORD_ALLOW_NETWORK
40                                     "%s %s %u\n", operation, address, port);                                     "%s %s %u\n", operation, address, port);
41  }  }
42    
# Line 47  static int ccs_audit_network_log(struct Line 47  static int ccs_audit_network_log(struct
47   * @min:     Pointer to store min address.   * @min:     Pointer to store min address.
48   * @max:     Pointer to store max address.   * @max:     Pointer to store max address.
49   *   *
50   * Returns 2 if @address is an IPv6, 1 if @address is an IPv4, 0 otherwise.   * Returns CCS_IP_ADDRESS_TYPE_IPv6 if @address is an IPv6,
51     * CCS_IP_ADDRESS_TYPE_IPv4 if @address is an IPv4,
52     * CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP otherwise.
53   */   */
54  int ccs_parse_ip_address(char *address, u16 *min, u16 *max)  int ccs_parse_ip_address(char *address, u16 *min, u16 *max)
55  {  {
# Line 65  int ccs_parse_ip_address(char *address, Line 67  int ccs_parse_ip_address(char *address,
67                          min[i] = htons(min[i]);                          min[i] = htons(min[i]);
68                          max[i] = htons(max[i]);                          max[i] = htons(max[i]);
69                  }                  }
70                  return 2;                  return CCS_IP_ADDRESS_TYPE_IPv6;
71          }          }
72          count = sscanf(address, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",          count = sscanf(address, "%hu.%hu.%hu.%hu-%hu.%hu.%hu.%hu",
73                         &min[0], &min[1], &min[2], &min[3],                         &min[0], &min[1], &min[2], &min[3],
# Line 75  int ccs_parse_ip_address(char *address, Line 77  int ccs_parse_ip_address(char *address,
77                                 + (((u8) min[2]) << 8) + (u8) min[3]);                                 + (((u8) min[2]) << 8) + (u8) min[3]);
78                  memmove(min, &ip, sizeof(ip));                  memmove(min, &ip, sizeof(ip));
79                  if (count == 8)                  if (count == 8)
80                          ip = htonl((((u8) max[0]) << 24) + (((u8) max[1]) << 16)                          ip = htonl((((u8) max[0]) << 24)
81                                       + (((u8) max[1]) << 16)
82                                     + (((u8) max[2]) << 8) + (u8) max[3]);                                     + (((u8) max[2]) << 8) + (u8) max[3]);
83                  memmove(max, &ip, sizeof(ip));                  memmove(max, &ip, sizeof(ip));
84                  return 1;                  return CCS_IP_ADDRESS_TYPE_IPv4;
85          }          }
86          return 0;          return CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP;
87    }
88    
89    /**
90     * ccs_print_ipv4 - Print an IPv4 address.
91     *
92     * @buffer:     Buffer to write to.
93     * @buffer_len: Size of @buffer.
94     * @min_ip:     Min address in host byte order.
95     * @max_ip:     Max address in host byte order.
96     *
97     * Returns nothing.
98     */
99    void ccs_print_ipv4(char *buffer, const int buffer_len,
100                        const u32 min_ip, const u32 max_ip)
101    {
102            memset(buffer, 0, buffer_len);
103            snprintf(buffer, buffer_len - 1, "%u.%u.%u.%u%c%u.%u.%u.%u",
104                     HIPQUAD(min_ip), min_ip == max_ip ? '\0' : '-',
105                     HIPQUAD(max_ip));
106  }  }
107    
108  #if !defined(NIP6)  #if !defined(NIP6)
# Line 96  int ccs_parse_ip_address(char *address, Line 118  int ccs_parse_ip_address(char *address,
118   *   *
119   * @buffer:     Buffer to write to.   * @buffer:     Buffer to write to.
120   * @buffer_len: Size of @buffer.   * @buffer_len: Size of @buffer.
121   * @ip:         Pointer to "struct in6_addr".   * @min_ip:     Pointer to "struct in6_addr".
122     * @max_ip:     Pointer to "struct in6_addr".
123   *   *
124   * Returns nothing.   * Returns nothing.
125   */   */
126  void ccs_print_ipv6(char *buffer, const int buffer_len,  void ccs_print_ipv6(char *buffer, const int buffer_len,
127                      const struct in6_addr *ip)                      const struct in6_addr *min_ip,
128                        const struct in6_addr *max_ip)
129  {  {
130          memset(buffer, 0, buffer_len);          memset(buffer, 0, buffer_len);
131          snprintf(buffer, buffer_len - 1, "%x:%x:%x:%x:%x:%x:%x:%x", NIP6(*ip));          snprintf(buffer, buffer_len - 1,
132                     "%x:%x:%x:%x:%x:%x:%x:%x%c%x:%x:%x:%x:%x:%x:%x:%x",
133                     NIP6(*min_ip), min_ip == max_ip ? '\0' : '-',
134                     NIP6(*max_ip));
135  }  }
136    
137  /**  /**
# Line 168  static int ccs_network_entry2(const bool Line 195  static int ccs_network_entry2(const bool
195          /* using host byte order to allow u32 comparison than memcmp().*/          /* using host byte order to allow u32 comparison than memcmp().*/
196          const u32 ip = ntohl(*address);          const u32 ip = ntohl(*address);
197          int error;          int error;
198          char buf[64];          char buf[128];
199          if (ccs_init_request_info(&r, NULL,          const struct ccs_domain_info * const domain = ccs_current_domain();
200                                    CCS_MAC_NETWORK_UDP_BIND + operation)          if (ccs_init_request_info(&r, CCS_MAC_NETWORK_UDP_BIND + operation)
201              == CCS_CONFIG_DISABLED)              == CCS_CONFIG_DISABLED)
202                  return 0;                  return 0;
         memset(buf, 0, sizeof(buf));  
203          if (is_ipv6)          if (is_ipv6)
204                  ccs_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)                  ccs_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)
205                                 address);                                 address, (const struct in6_addr *) address);
206          else          else
207                  snprintf(buf, sizeof(buf) - 1, "%u.%u.%u.%u", HIPQUAD(ip));                  ccs_print_ipv4(buf, sizeof(buf), ip, ip);
208          do {          do {
209                  error = -EPERM;                  error = -EPERM;
210                  list_for_each_entry_rcu(ptr, &r.domain->acl_info_list, list) {                  list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
211                          struct ccs_ip_network_acl *acl;                          struct ccs_ip_network_acl *acl;
212                          if (ptr->is_deleted ||                          if (ptr->is_deleted ||
213                              ptr->type != CCS_TYPE_IP_NETWORK_ACL)                              ptr->type != CCS_TYPE_IP_NETWORK_ACL)
# Line 250  static int ccs_network_entry(const bool Line 276  static int ccs_network_entry(const bool
276          return error;          return error;
277  }  }
278    
279    static bool ccs_same_ip_network_acl(const struct ccs_acl_info *a,
280                                        const struct ccs_acl_info *b)
281    {
282            const struct ccs_ip_network_acl *p1 = container_of(a, typeof(*p1),
283                                                               head);
284            const struct ccs_ip_network_acl *p2 = container_of(b, typeof(*p2),
285                                                               head);
286            return ccs_same_acl_head(&p1->head, &p2->head)
287                    && p1->address_type == p2->address_type &&
288                    p1->address.ipv4.min == p2->address.ipv4.min &&
289                    p1->address.ipv6.min == p2->address.ipv6.min &&
290                    p1->address.ipv4.max == p2->address.ipv4.max &&
291                    p1->address.ipv6.max == p2->address.ipv6.max &&
292                    p1->address.group == p2->address.group &&
293                    ccs_same_number_union(&p1->port, &p2->port);
294    }
295    
296    static bool ccs_merge_ip_network_acl(struct ccs_acl_info *a,
297                                         struct ccs_acl_info *b,
298                                         const bool is_delete)
299    {
300            u8 * const a_perm = &container_of(a, struct ccs_ip_network_acl, head)
301                    ->perm;
302            u8 perm = *a_perm;
303            const u8 b_perm = container_of(b, struct ccs_ip_network_acl, head)
304                    ->perm;
305            if (is_delete)
306                    perm &= ~b_perm;
307            else
308                    perm |= b_perm;
309            *a_perm = perm;
310            return !perm;
311    }
312    
313  /**  /**
314   * ccs_write_network_policy - Write "struct ccs_ip_network_acl" list.   * ccs_write_network - Write "struct ccs_ip_network_acl" list.
315   *   *
316   * @data:      String to parse.   * @data:      String to parse.
317   * @domain:    Pointer to "struct ccs_domain_info".   * @domain:    Pointer to "struct ccs_domain_info".
# Line 260  static int ccs_network_entry(const bool Line 320  static int ccs_network_entry(const bool
320   *   *
321   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
322   */   */
323  int ccs_write_network_policy(char *data, struct ccs_domain_info *domain,  int ccs_write_network(char *data, struct ccs_domain_info *domain,
324                               struct ccs_condition *condition,                        struct ccs_condition *condition, const bool is_delete)
                              const bool is_delete)  
325  {  {
         struct ccs_ip_network_acl *entry = NULL;  
         struct ccs_acl_info *ptr;  
326          struct ccs_ip_network_acl e = {          struct ccs_ip_network_acl e = {
327                  .head.type = CCS_TYPE_IP_NETWORK_ACL,                  .head.type = CCS_TYPE_IP_NETWORK_ACL,
328                  .head.cond = condition,                  .head.cond = condition,
# Line 316  int ccs_write_network_policy(char *data, Line 373  int ccs_write_network_policy(char *data,
373          else          else
374                  return -EINVAL;                  return -EINVAL;
375          switch (ccs_parse_ip_address(w[2], min_address, max_address)) {          switch (ccs_parse_ip_address(w[2], min_address, max_address)) {
376          case 2:          case CCS_IP_ADDRESS_TYPE_IPv6:
377                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv6;                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv6;
378                  e.address.ipv6.min = ccs_get_ipv6_address((struct in6_addr *)                  e.address.ipv6.min = ccs_get_ipv6_address((struct in6_addr *)
379                                                            min_address);                                                            min_address);
# Line 325  int ccs_write_network_policy(char *data, Line 382  int ccs_write_network_policy(char *data,
382                  if (!e.address.ipv6.min || !e.address.ipv6.max)                  if (!e.address.ipv6.min || !e.address.ipv6.max)
383                          goto out;                          goto out;
384                  break;                  break;
385          case 1:          case CCS_IP_ADDRESS_TYPE_IPv4:
386                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv4;                  e.address_type = CCS_IP_ADDRESS_TYPE_IPv4;
387                  /* use host byte order to allow u32 comparison.*/                  /* use host byte order to allow u32 comparison.*/
388                  e.address.ipv4.min = ntohl(*(u32 *) min_address);                  e.address.ipv4.min = ntohl(*(u32 *) min_address);
# Line 335  int ccs_write_network_policy(char *data, Line 392  int ccs_write_network_policy(char *data,
392                  if (w[2][0] != '@')                  if (w[2][0] != '@')
393                          return -EINVAL;                          return -EINVAL;
394                  e.address_type = CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP;                  e.address_type = CCS_IP_ADDRESS_TYPE_ADDRESS_GROUP;
395                  e.address.group = ccs_get_address_group(w[2] + 1);                  e.address.group = ccs_get_group(w[2] + 1, CCS_ADDRESS_GROUP);
396                  if (!e.address.group)                  if (!e.address.group)
397                          return -ENOMEM;                          return -ENOMEM;
398                  break;                  break;
399          }          }
400          if (!ccs_parse_number_union(w[3], &e.port))          if (!ccs_parse_number_union(w[3], &e.port))
401                  goto out;                  goto out;
402          if (!is_delete)          error = ccs_update_domain(&e.head, sizeof(e), is_delete, domain,
403                  entry = kmalloc(sizeof(e), GFP_KERNEL);                                    ccs_same_ip_network_acl,
404          mutex_lock(&ccs_policy_lock);                                    ccs_merge_ip_network_acl);
         list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {  
                 struct ccs_ip_network_acl *acl =  
                         container_of(ptr, struct ccs_ip_network_acl, head);  
                 if (ptr->type != CCS_TYPE_IP_NETWORK_ACL ||  
                     ptr->cond != condition ||  
                     ccs_memcmp(acl, &e, offsetof(typeof(e), address_type),  
                                sizeof(e)))  
                         continue;  
                 if (is_delete) {  
                         acl->perm &= ~e.perm;  
                         if (!acl->perm)  
                                 ptr->is_deleted = true;  
                 } else {  
                         if (ptr->is_deleted)  
                                 acl->perm = 0;  
                         acl->perm |= e.perm;  
                         ptr->is_deleted = false;  
                 }  
                 error = 0;  
                 break;  
         }  
         if (!is_delete && error && ccs_commit_ok(entry, &e, sizeof(e))) {  
                 ccs_add_domain_acl(domain, &entry->head);  
                 entry = NULL;  
                 error = 0;  
         }  
         mutex_unlock(&ccs_policy_lock);  
405   out:   out:
406          if (w[2][0] == '@')          if (w[2][0] == '@')
407                  ccs_put_address_group(e.address.group);                  ccs_put_group(e.address.group);
408          else if (e.address_type == CCS_IP_ADDRESS_TYPE_IPv6) {          else if (e.address_type == CCS_IP_ADDRESS_TYPE_IPv6) {
409                  ccs_put_ipv6_address(e.address.ipv6.min);                  ccs_put_ipv6_address(e.address.ipv6.min);
410                  ccs_put_ipv6_address(e.address.ipv6.max);                  ccs_put_ipv6_address(e.address.ipv6.max);
411          }          }
412          ccs_put_number_union(&e.port);          ccs_put_number_union(&e.port);
         kfree(entry);  
413          return error;          return error;
414  }  }
415    
# Line 393  int ccs_write_network_policy(char *data, Line 422  int ccs_write_network_policy(char *data,
422   *   *
423   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
424   */   */
425  static inline int ccs_network_listen_acl(const bool is_ipv6, const u8 *address,  static int ccs_network_listen_acl(const bool is_ipv6, const u8 *address,
426                                           const u16 port)                                    const u16 port)
427  {  {
428          return ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_LISTEN,          return ccs_network_entry(is_ipv6, CCS_NETWORK_TCP_LISTEN,
429                                   (const u32 *) address, ntohs(port));                                   (const u32 *) address, ntohs(port));
# Line 410  static inline int ccs_network_listen_acl Line 439  static inline int ccs_network_listen_acl
439   *   *
440   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
441   */   */
442  static inline int ccs_network_connect_acl(const bool is_ipv6,  static int ccs_network_connect_acl(const bool is_ipv6, const int sock_type,
443                                            const int sock_type,                                     const u8 *address, const u16 port)
                                           const u8 *address, const u16 port)  
444  {  {
445          u8 operation;          u8 operation;
446          switch (sock_type) {          switch (sock_type) {
# Line 466  static int ccs_network_bind_acl(const bo Line 494  static int ccs_network_bind_acl(const bo
494   *   *
495   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
496   */   */
497  static inline int ccs_network_accept_acl(const bool is_ipv6, const u8 *address,  static int ccs_network_accept_acl(const bool is_ipv6, const u8 *address,
498                                           const u16 port)                                    const u16 port)
499  {  {
500          int retval;          int retval;
501          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;          current->ccs_flags |= CCS_DONT_SLEEP_ON_ENFORCE_ERROR;
# Line 487  static inline int ccs_network_accept_acl Line 515  static inline int ccs_network_accept_acl
515   *   *
516   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
517   */   */
518  static inline int ccs_network_sendmsg_acl(const bool is_ipv6,  static int ccs_network_sendmsg_acl(const bool is_ipv6, const int sock_type,
519                                            const int sock_type,                                     const u8 *address, const u16 port)
                                           const u8 *address, const u16 port)  
520  {  {
521          u8 operation;          u8 operation;
522          if (sock_type == SOCK_DGRAM)          if (sock_type == SOCK_DGRAM)
# Line 510  static inline int ccs_network_sendmsg_ac Line 537  static inline int ccs_network_sendmsg_ac
537   *   *
538   * Returns 0 on success, negative value otherwise.   * Returns 0 on success, negative value otherwise.
539   */   */
540  static inline int ccs_network_recvmsg_acl(const bool is_ipv6,  static int ccs_network_recvmsg_acl(const bool is_ipv6, const int sock_type,
541                                            const int sock_type,                                     const u8 *address, const u16 port)
                                           const u8 *address, const u16 port)  
542  {  {
543          int retval;          int retval;
544          const u8 operation          const u8 operation
# Line 525  static inline int ccs_network_recvmsg_ac Line 551  static inline int ccs_network_recvmsg_ac
551          return retval;          return retval;
552  }  }
553    
554    #ifndef CONFIG_NET
555    
556    void __init ccs_network_init(void)
557    {
558    }
559    
560    #else
561    
562  #define MAX_SOCK_ADDR 128 /* net/socket.c */  #define MAX_SOCK_ADDR 128 /* net/socket.c */
563    
564  /* Check permission for creating a socket. */  /* Check permission for creating a socket. */
# Line 938  void __init ccs_network_init(void) Line 972  void __init ccs_network_init(void)
972          ccsecurity_ops.socket_recvmsg_permission =          ccsecurity_ops.socket_recvmsg_permission =
973                  __ccs_socket_recvmsg_permission;                  __ccs_socket_recvmsg_permission;
974  }  }
975    
976    #endif

Legend:
Removed from v.3502  
changed lines
  Added in v.3695

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