View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16
    17  package org.jboss.netty.handler.ipfilter;
    18
    19  import java.net.InetAddress;
    20  import java.net.UnknownHostException;
    21  import java.util.regex.Pattern;
    22
    23  import org.jboss.netty.logging.InternalLogger;
    24  import org.jboss.netty.logging.InternalLoggerFactory;
    25
    26  /**
    27   * The Class PatternRule represents an IP filter rule using string patterns.
    28   * <br>
    29   * Rule Syntax:
    30   * <br>
    31   * <pre>
    32   * Rule ::= [n|i]:address          n stands for computer name, i for ip address
    33   * address ::= &lt;regex&gt; | localhost
    34   * regex is a regular expression with '*' as multi character and '?' as single character wild card
    35   * </pre>
    36   * <br>
    37   * Example: allow localhost:
    38   * <br>
    39   * new PatternRule(true, "n:localhost")
    40   * <br>
    41   * Example: allow local lan:
    42   * <br>
    43   * new PatternRule(true, "i:192.168.0.*")
    44   * <br>
    45   * Example: block all
    46   * <br>
    47   * new PatternRule(false, "n:*")
    48   * <br>
    49   */
    50  public class PatternRule implements IpFilterRule, Comparable<Object> {
    51      private static final InternalLogger logger = InternalLoggerFactory.getInstance(PatternRule.class);
    52
    53      private Pattern ipPattern;
    54
    55      private Pattern namePattern;
    56
    57      private boolean isAllowRule = true;
    58
    59      private boolean localhost;
    60
    61      private final String pattern;
    62
    63      /**
    64       * Instantiates a new pattern rule.
    65       *
    66       * @param allow   indicates if this is an allow or block rule
    67       * @param pattern the filter pattern
    68       */
    69      public PatternRule(boolean allow, String pattern) {
    70          isAllowRule = allow;
    71          this.pattern = pattern;
    72          parse(pattern);
    73      }
    74
    75      /**
    76       * returns the pattern.
    77       *
    78       * @return the pattern
    79       */
    80      public String getPattern() {
    81          return pattern;
    82      }
    83
    84      public boolean isAllowRule() {
    85          return isAllowRule;
    86      }
    87
    88      public boolean isDenyRule() {
    89          return !isAllowRule;
    90      }
    91
    92      public boolean contains(InetAddress inetAddress) {
    93          if (localhost) {
    94              if (isLocalhost(inetAddress)) {
    95                  return true;
    96              }
    97          }
    98          if (ipPattern != null) {
    99              if (ipPattern.matcher(inetAddress.getHostAddress()).matches()) {
    100                 return true;
    101             }
    102         }
    103         if (namePattern != null) {
    104             if (namePattern.matcher(inetAddress.getHostName()).matches()) {
    105                 return true;
    106             }
    107         }
    108         return false;
    109     }
    110
    111     private void parse(String pattern) {
    112         if (pattern == null) {
    113             return;
    114         }
    115
    116         String[] acls = pattern.split(",");
    117
    118         String ip = "";
    119         String name = "";
    120         for (String c : acls) {
    121             c = c.trim();
    122             if (c.equals("n:localhost")) {
    123                 localhost = true;
    124             } else if (c.startsWith("n:")) {
    125                 name = addRule(name, c.substring(2));
    126             } else if (c.startsWith("i:")) {
    127                 ip = addRule(ip, c.substring(2));
    128             }
    129         }
    130         if (ip.length() != 0) {
    131             ipPattern = Pattern.compile(ip);
    132         }
    133         if (name.length() != 0) {
    134             namePattern = Pattern.compile(name);
    135         }
    136     }
    137
    138     private static String addRule(String pattern, String rule) {
    139         if (rule == null || rule.length() == 0) {
    140             return pattern;
    141         }
    142         if (pattern.length() != 0) {
    143             pattern += "|";
    144         }
    145         rule = rule.replaceAll("\\.", "\\\\.");
    146         rule = rule.replaceAll("\\*", ".*");
    147         rule = rule.replaceAll("\\?", ".");
    148         pattern += "(" + rule + ")";
    149         return pattern;
    150     }
    151
    152     private static boolean isLocalhost(InetAddress address) {
    153         try {
    154             if (address.equals(InetAddress.getLocalHost())) {
    155                 return true;
    156             }
    157         } catch (UnknownHostException e) {
    158             if (logger.isInfoEnabled()) {
    159                 logger.info("error getting ip of localhost", e);
    160             }
    161         }
    162         try {
    163             InetAddress[] addrs = InetAddress.getAllByName("127.0.0.1");
    164             for (InetAddress addr : addrs) {
    165                 if (addr.equals(address)) {
    166                     return true;
    167                 }
    168             }
    169         } catch (UnknownHostException e) {
    170             if (logger.isInfoEnabled()) {
    171                 logger.info("error getting ip of localhost", e);
    172             }
    173         }
    174         return false;
    175
    176     }
    177
    178     public int compareTo(Object o) {
    179         if (o == null) {
    180             return -1;
    181         }
    182         if (!(o instanceof PatternRule)) {
    183             return -1;
    184         }
    185         PatternRule p = (PatternRule) o;
    186         if (p.isAllowRule() && !isAllowRule) {
    187             return -1;
    188         }
    189         if (pattern == null && p.pattern == null) {
    190             return 0;
    191         }
    192         if (pattern != null) {
    193             return pattern.compareTo(p.getPattern());
    194         }
    195         return -1;
    196     }
    197
    198 }