📄 smarthostauthorizationrules.java
字号:
/* * Copyright (c) 2003, The Regents of the University of California, through * Lawrence Berkeley National Laboratory (subject to receipt of any required * approvals from the U.S. Dept. of Energy). All rights reserved. */package gov.lbl.dsd.sea.nio.auth;import gov.lbl.dsd.sea.nio.util.ExtendedProperties;import java.io.IOException;import java.net.InetAddress;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Set;import java.util.regex.Pattern;/** * Powerful authorization rules to be used by {@link SmartHostAuthorizer}; * Supports allow and deny rules based on exact or patterned DNS host names, * exact or patterned IP addresses, as well as regular expressions on * "hostName/IPaddress" pairs. * <p> * Can be configured programmatically or via a configuration file (see file * "authorization.properties") for an example. * * @author whoschek@lbl.gov * @author $Author: hoschek3 $ * @version $Revision: 1.7 $, $Date: 2004/12/01 20:59:31 $ */public class SmartHostAuthorizationRules implements HostAuthorizationRules, java.io.Serializable { /** Meta match all hosts (no matter what DNS name or IP address) */ public static final String ALL = "all"; /** Relative to localhost, meta match loopback hosts (including localhost) */ public static final String LOOPBACK = "loopback"; /** Relative to localhost, meta match hosts in the same DNS domain */ public static final String COMMON_DOMAIN = "common-domain"; /** Relative to localhost, meta match hosts in the same IP subnet */ public static final String COMMON_SUBNET = "common-subnet"; // the rules for various checks: private Set metaDirectives = new HashSet(); private Set hostAddresses = new HashSet(); private Set hostAddressPatterns = new HashSet(); private Set hostNames = new HashSet(); private Set hostNamePatterns = new HashSet(); private List regexes = new ArrayList(); private ExtendedProperties properties = new ExtendedProperties(); // keep around just for an easy toString() private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(SmartHostAuthorizationRules.class); /** * Creates an empty instance with no rules (isMatch(x) returns false). */ public SmartHostAuthorizationRules() {} /** * Creates an authorizer from the given configuration properties. * * @param properties the configuration properties to use */ public static SmartHostAuthorizer createHostAuthorizer(ExtendedProperties properties) { return new SmartHostAuthorizer( properties.getBoolean("allowBeforeDeny", true), new SmartHostAuthorizationRules().addRules("allow", properties), new SmartHostAuthorizationRules().addRules("deny", properties) ); } /** * Creates an authorizer from the properties in the given configuration file. * * @param fileName the configuration file to use * @throws IOException */ public static SmartHostAuthorizer createHostAuthorizer(String fileName) throws IOException { return createHostAuthorizer(new ExtendedProperties(fileName)); } /** * Adds the given host or pattern to the set of rules. * @param host the host to pattern to add. * <p> * Exact address example: "131.243.2.165", Prefix patterned address example: "131.243." * <p> * Exact name example: "doggy.lbl.gov", Suffix patterned name example: ".lbl.gov" * <p> * Meta pattern examples: "all", "loopback", "common-domain", "common-subnet" * @return this (for convenience only) */ public SmartHostAuthorizationRules addHost(String host) { this.checkString(host); host = host.toLowerCase(); if (host.equals(ALL) || host.equals(LOOPBACK)) { this.metaDirectives.add(host); return this; } if (host.equals(COMMON_DOMAIN)) { String hostName = getLocalHost().getHostName(); String domainPattern = hostName.substring(hostName.indexOf(".")); //log.debug("hostName="+hostName); //log.debug("domainPattern="+domainPattern); this.hostNamePatterns.add(domainPattern); return this; } if (host.equals(COMMON_SUBNET)) { String hostAddress = getLocalHost().getHostAddress(); String addressPattern = hostAddress.substring(0, hostAddress.lastIndexOf(".")+1); //log.debug("hostAddress="+hostAddress); //log.debug("addressPattern="+addressPattern); this.hostAddressPatterns.add(addressPattern); return this; } if (this.isHostName(host)) { if (host.startsWith(".")) this.hostNamePatterns.add(host); else this.hostNames.add(host); return this; } if (host.endsWith(".")) this.hostAddressPatterns.add(host); else this.hostAddresses.add(host); return this; } /** * Adds the given regular expression on "hostName/IPaddress" to the set of rules. * @param regex Example: "clusternode.+?\.lbl\.gov/.*" * @return this (for convenience only) */ public SmartHostAuthorizationRules addRegex(String regex) { this.checkString(regex); this.regexes.add(Pattern.compile(regex)); return this; } /** * Reads all rules for the given mode from the given configuration * properties and adds them to the current set of rules. * * @param mode for example "allow" or "deny" * @param properties the configuration properties to read from * @return this (for convenience only) */ protected SmartHostAuthorizationRules addRules(String mode, ExtendedProperties properties) { String[] strings; strings = properties.getStringArray(mode + ""); for (int i=0; i < strings.length; i++) addHost(strings[i]); strings = properties.getStringArray(mode + ".regex"); for (int i=0; i < strings.length; i++) addRegex(strings[i]); this.properties = properties; return this; } /** * Returns whether or not the given host (aka InetAddress) matches ANY of * the current rules. * * @return true if at least one rule matches; false otherwise */ public boolean isMatch(InetAddress address) { // compare meta wildcards if (metaDirectives.size() > 0) { if (metaDirectives.contains(ALL)) { return true; } if (metaDirectives.contains(LOOPBACK) && address.isLoopbackAddress()) { return true; } } // compare exact IP address if (hostAddresses.size() > 0) { String hostAddress = address.getHostAddress(); if (hostAddresses.contains(hostAddress)) { return true; } } // compare prefix patterned IP address if (hostAddressPatterns.size() > 0) { String hostAddress = address.getHostAddress(); Iterator iter = hostAddressPatterns.iterator(); while (iter.hasNext()) { String pattern = (String) iter.next(); if (hostAddress.startsWith(pattern)) { return true; } } } // compare exact host name if (hostNames.size() > 0) { String hostName = address.getHostName(); if (hostNames.contains(hostName)) { return true; } } // compare suffix patterned host name if (hostNamePatterns.size() > 0) { String hostName = address.getHostName(); Iterator iter = hostNamePatterns.iterator(); while (iter.hasNext()) { String pattern = (String) iter.next(); if (hostName.endsWith(pattern)) { return true; } } } // compare regular expressions on "hostName/IPaddress" if (regexes.size() > 0) { String nameAndAddress = address.getHostName() + "/" + address.getHostAddress(); Iterator iter = regexes.iterator(); while (iter.hasNext()) { Pattern regex = (Pattern) iter.next(); if (regex.matcher(nameAndAddress).matches()) { return true; } } } return false; } /** * Returns a summary string representation of the receiver. */ public String toString() { return this.getClass().getName() + "[" + toString(this.properties) + "]"; } private boolean isHostName(String str) { for (int i=0; i < str.length(); i++) { if (Character.isLetter(str.charAt(i))) return true; } return false; } /** Sanity check */ private void checkString(String str) { if (str==null || str.length()==0) throw new IllegalArgumentException("str=["+str+"]"); } private static InetAddress getLocalHost() { try { return InetAddress.getLocalHost(); } catch (UnknownHostException e) { throw new RuntimeException("Oops, should never happen", e); } } /** * Converts properties to a summary string */ private String toString(ExtendedProperties properties) { StringBuffer buf = new StringBuffer(); Iterator iter = properties.getKeys(); while (iter.hasNext()) { String key = (String) iter.next(); Object value = properties.get(key); buf.append("\n" + key + " => " + value); } return buf.toString(); } /** * Program to quickly test whether or not a given host is allowed; * Useful to assist in becoming familiar with the configuration file syntax; * Example usage: java [class] [configFileName] [hostName] */ public static void main(String[] args) throws IOException { String fileName = "authorization.properties"; if (args.length > 0) fileName = args[0]; String hostName = "doggy.lbl.gov"; if (args.length > 1) hostName = args[1]; int runs = 1; if (args.length > 2) runs = Integer.parseInt(args[2]); HostAuthorizer authorizer = createHostAuthorizer(fileName); InetAddress address = InetAddress.getByName(hostName); boolean isAllowed = false; long start = System.currentTimeMillis(); for (int i=0; i < runs; i++) isAllowed = authorizer.isAllowed(address); long end = System.currentTimeMillis(); System.out.println("isAllowed="+ isAllowed); System.out.println("inetAddress="+ address); System.out.println("inetAddress.getCanonicalHostName="+ address.getCanonicalHostName()); System.out.println("localHost="+ InetAddress.getLocalHost()); System.out.println("hostAuthorizer="+ authorizer); System.out.println("secs="+ (end-start) / 1000.0f); System.out.println("iters/sec="+ runs / ((end-start) / 1000.0f)); }// private void logAddress(InetAddress address) {// log.fatal("hostName="+address.getHostName());// log.fatal("toString="+address.toString());// log.fatal("hostAddress="+address.getHostAddress());// log.fatal("canon="+address.getCanonicalHostName());// log.fatal("isLoopbackAddress="+address.isLoopbackAddress());// log.fatal("isSiteLocalAddress="+address.isSiteLocalAddress());// log.fatal("isAnyLocalAddress="+address.isAnyLocalAddress());// //InetAddressUtil util = new InetAddressUtil();// log.fatal("class="+InetAddressInfo.getSubnetClassString(address));// log.fatal("domainlevels="+InetAddressInfo.getDomainLevels(address));// log.fatal("subnetMask="+InetAddressInfo.getSubnetMaskString(address));// log.fatal("commonSubnet="+new InetAddressInfo(getLocalHost()).commonSubnet(address));// log.fatal("commonDomain="+(new InetAddressInfo(getLocalHost()).commonDomainLevels(address) == 2));// log.fatal("commonDomainLevels="+new InetAddressInfo(getLocalHost()).commonDomainLevels(address));// //log.fatal("domainName="+getDomainName(address));// }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -