/*
* JBoss, Home of Professional Open Source
* Copyright 2010, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.netty.handler.ipfilter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory;
/**
* The Class PatternRule represents an IP filter rule using string patterns.
* <br>
* Rule Syntax:
* <br>
* <pre>
* Rule ::= [n|i]:address n stands for computer name, i for ip address
* address ::= <regex> | localhost
* regex is a regular expression with '*' as multi character and '?' as single character wild card
* </pre>
* <br>
* Example: allow localhost:
* <br>
* new PatternRule(true, "n:localhost")
* <br>
* Example: allow local lan:
* <br>
* new PatternRule(true, "i:192.168.0.*")
* <br>
* Example: block all
* <br>
* new PatternRule(false, "n:*")
* <br>
*
* @author Ron
*/
public class PatternRule implements IpFilterRule, Comparable<Object>
{
private static final InternalLogger logger = InternalLoggerFactory.getInstance(PatternRule.class);
private Pattern ipPattern = null;
private Pattern namePattern = null;
private boolean isAllowRule = true;
private boolean localhost = false;
private String pattern = null;
/**
* Instantiates a new pattern rule.
*
* @param allow indicates if this is an allow or block rule
* @param pattern the filter pattern
*/
public PatternRule(boolean allow, String pattern)
{
this.isAllowRule = allow;
this.pattern = pattern;
parse(pattern);
}
/**
* returns the pattern.
*
* @return the pattern
*/
public String getPattern()
{
return this.pattern;
}
/* (non-Javadoc)
* @see org.jboss.netty.handler.ipfilter.IpFilterRule#isAllowRule()
*/
public boolean isAllowRule()
{
return isAllowRule;
}
/* (non-Javadoc)
* @see org.jboss.netty.handler.ipfilter.IpFilterRule#isDenyRule()
*/
public boolean isDenyRule()
{
return !isAllowRule;
}
/* (non-Javadoc)
* @see org.jboss.netty.handler.ipfilter.IpSet#contains(java.net.InetAddress)
*/
public boolean contains(InetAddress inetAddress)
{
if (localhost)
if (isLocalhost(inetAddress))
return true;
if (ipPattern != null)
if (ipPattern.matcher(inetAddress.getHostAddress()).matches())
return true;
if (namePattern != null)
if (namePattern.matcher(inetAddress.getHostName()).matches())
return true;
return false;
}
private void parse(String pattern)
{
if (pattern == null)
return;
String[] acls = pattern.split(",");
String ip = "";
String name = "";
for (String c : acls)
{
c = c.trim();
if (c.equals("n:localhost"))
this.localhost = true;
else if (c.startsWith("n:"))
name = addRule(name, c.substring(2));
else if (c.startsWith("i:"))
ip = addRule(ip, c.substring(2));
}
if (ip.length() != 0)
ipPattern = Pattern.compile(ip);
if (name.length() != 0)
namePattern = Pattern.compile(name);
}
private String addRule(String pattern, String rule)
{
if (rule == null || rule.length() == 0)
return pattern;
if (pattern.length() != 0)
pattern += "|";
rule = rule.replaceAll("\\.", "\\\\.");
rule = rule.replaceAll("\\*", ".*");
rule = rule.replaceAll("\\?", ".");
pattern += "(" + rule + ")";
return pattern;
}
private boolean isLocalhost(InetAddress address)
{
try
{
if (address.equals(InetAddress.getLocalHost()))
return true;
}
catch (UnknownHostException e)
{
logger.info("error getting ip of localhost", e);
}
try
{
InetAddress[] addrs = InetAddress.getAllByName("127.0.0.1");
for (InetAddress addr : addrs)
if (addr.equals(address))
return true;
}
catch (UnknownHostException e)
{
logger.info("error getting ip of localhost", e);
}
return false;
}
/* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compareTo(Object o)
{
if (o == null)
return -1;
if (!(o instanceof PatternRule))
return -1;
PatternRule p = (PatternRule) o;
if (p.isAllowRule() && !this.isAllowRule)
return -1;
if (this.pattern == null && p.pattern == null)
return 0;
if (this.pattern != null)
return this.pattern.compareTo(p.getPattern());
return -1;
}
}