001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008 Sun Microsystems, Inc. 015 * Portions Copyright 2013-2015 ForgeRock AS. 016 */ 017package org.opends.server.authorization.dseecompat; 018import org.forgerock.i18n.LocalizableMessage; 019 020import static org.opends.messages.AccessControlMessages.*; 021import java.util.regex.Pattern; 022import java.util.*; 023import java.net.InetAddress; 024 025/** 026 * This class represents a single ACI's IP bind rule expression. It is possible 027 * for that expression to contain several IP addresses to evaluate, so the 028 * class contains a list of classes that can evaluate a remote clients IP 029 * address for each IP address parsed from the bind rule. 030 */ 031public class IP implements KeywordBindRule { 032 033 /** 034 * Regular expression used to do a quick check on the characters in a 035 * bind rule address. These are all of the valid characters that may 036 * appear in an bind rule address part. 037 */ 038 private static final String ipRegEx = 039 "((?i)[\\.{1}[a-f]\\d:\\+{1}\\*/{1}\\t\\[{1}\\]{1}]+(?-i))"; 040 041 /** 042 * List of the pattern classes, one for each address decoded from the bind 043 * rule. 044 */ 045 private List<PatternIP> patternIPList; 046 047 /** The type of the bind rule (!= or =). */ 048 private EnumBindRuleType type; 049 050 /** 051 * Create a class representing the IP bind rule expressions for this ACI. 052 * @param patternIPList A list of PatternIP objects representing the IP 053 * bind rule expressions decoded from ACI. 054 * @param type An enumeration representing the expression type. 055 */ 056 private IP(List<PatternIP> patternIPList, EnumBindRuleType type) { 057 this.patternIPList=patternIPList; 058 this.type=type; 059 } 060 061 /** 062 * Decodes the provided IP bind rule expression string and returns an 063 * IP class the can be used to evaluate remote clients IP addresses. 064 * 065 * @param expr The expression string from the ACI IP bind rule. 066 * @param type An enumeration representing the expression type. 067 * @return A class that can be used to evaluate remote clients IP 068 * addresses. 069 * @throws AciException If there is a parsing error. 070 */ 071 public static KeywordBindRule decode(String expr, EnumBindRuleType type) 072 throws AciException { 073 //Split on the ','. 074 String[] ipStrs=expr.split("\\,", -1); 075 List<PatternIP> patternIPList= new LinkedList<>(); 076 for (String ipStr : ipStrs) { 077 if (!Pattern.matches(ipRegEx, ipStr)) { 078 LocalizableMessage message = 079 WARN_ACI_SYNTAX_INVALID_IP_EXPRESSION.get(expr); 080 throw new AciException(message); 081 } 082 PatternIP ipPattern = PatternIP.decode(ipStr); 083 patternIPList.add(ipPattern); 084 } 085 return new IP(patternIPList, type); 086 } 087 088 /** 089 * Perform an evaluation using the provided evaluation context's remote 090 * IP address information. 091 * 092 * @param evalCtx An evaluation context containing the remote clients 093 * IP address information. 094 * 095 * @return An enumeration representing if the address matched. 096 */ 097 public EnumEvalResult evaluate(AciEvalContext evalCtx) { 098 InetAddress remoteAddr=evalCtx.getRemoteAddress(); 099 return evaluate(remoteAddr); 100 } 101 102 /** 103 * Perform an evaluation using the InetAddress. 104 * 105 * @param addr The InetAddress to evaluate against PatternIP classes. 106 * @return An enumeration representing if the address matched one 107 * of the patterns. 108 */ 109 EnumEvalResult evaluate(InetAddress addr) { 110 EnumEvalResult matched=EnumEvalResult.FALSE; 111 Iterator<PatternIP> it=patternIPList.iterator(); 112 for(; it.hasNext() && matched != EnumEvalResult.TRUE && 113 matched != EnumEvalResult.ERR;) { 114 PatternIP patternIP=it.next(); 115 matched=patternIP.evaluate(addr); 116 } 117 return matched.getRet(type, false); 118 } 119 120 /** {@inheritDoc} */ 121 @Override 122 public String toString() { 123 final StringBuilder sb = new StringBuilder(); 124 toString(sb); 125 return sb.toString(); 126 } 127 128 /** {@inheritDoc} */ 129 @Override 130 public final void toString(StringBuilder buffer) { 131 buffer.append(super.toString()); 132 } 133 134}