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-2016 ForgeRock AS. 016 */ 017package org.opends.server.authorization.dseecompat; 018 019import static org.opends.messages.AccessControlMessages.*; 020 021import java.net.InetAddress; 022import java.util.Iterator; 023import java.util.LinkedList; 024import java.util.List; 025import java.util.regex.Pattern; 026 027/** 028 * This class represents a single ACI's IP bind rule expression. It is possible 029 * for that expression to contain several IP addresses to evaluate, so the 030 * class contains a list of classes that can evaluate a remote clients IP 031 * address for each IP address parsed from the bind rule. 032 */ 033public class IP implements KeywordBindRule { 034 /** 035 * Regular expression used to do a quick check on the characters in a 036 * bind rule address. These are all of the valid characters that may 037 * appear in an bind rule address part. 038 */ 039 private static final Pattern ipRegEx = 040 Pattern.compile("((?i)[\\.{1}[a-f]\\d:\\+{1}\\*/{1}\\t\\[{1}\\]{1}]+(?-i))"); 041 042 /** List of the pattern classes, one for each address decoded from the bind rule. */ 043 private final List<PatternIP> patternIPList; 044 /** The type of the bind rule (!= or =). */ 045 private final EnumBindRuleType type; 046 047 /** 048 * Create a class representing the IP bind rule expressions for this ACI. 049 * @param patternIPList A list of PatternIP objects representing the IP 050 * bind rule expressions decoded from ACI. 051 * @param type An enumeration representing the expression type. 052 */ 053 private IP(List<PatternIP> patternIPList, EnumBindRuleType type) { 054 this.patternIPList=patternIPList; 055 this.type=type; 056 } 057 058 /** 059 * Decodes the provided IP bind rule expression string and returns an 060 * IP class the can be used to evaluate remote clients IP addresses. 061 * 062 * @param expr The expression string from the ACI IP bind rule. 063 * @param type An enumeration representing the expression type. 064 * @return A class that can be used to evaluate remote clients IP 065 * addresses. 066 * @throws AciException If there is a parsing error. 067 */ 068 public static KeywordBindRule decode(String expr, EnumBindRuleType type) 069 throws AciException { 070 //Split on the ','. 071 String[] ipStrs=expr.split("\\,", -1); 072 List<PatternIP> patternIPList= new LinkedList<>(); 073 for (String ipStr : ipStrs) { 074 if (!ipRegEx.matcher(ipStr).matches()) { 075 throw new AciException(WARN_ACI_SYNTAX_INVALID_IP_EXPRESSION.get(expr)); 076 } 077 patternIPList.add(PatternIP.decode(ipStr)); 078 } 079 return new IP(patternIPList, type); 080 } 081 082 /** 083 * Perform an evaluation using the provided evaluation context's remote 084 * IP address information. 085 * 086 * @param evalCtx An evaluation context containing the remote clients 087 * IP address information. 088 * 089 * @return An enumeration representing if the address matched. 090 */ 091 @Override 092 public EnumEvalResult evaluate(AciEvalContext evalCtx) { 093 return evaluate(evalCtx.getRemoteAddress()); 094 } 095 096 /** 097 * Perform an evaluation using the InetAddress. 098 * 099 * @param addr The InetAddress to evaluate against PatternIP classes. 100 * @return An enumeration representing if the address matched one 101 * of the patterns. 102 */ 103 EnumEvalResult evaluate(InetAddress addr) { 104 EnumEvalResult matched=EnumEvalResult.FALSE; 105 Iterator<PatternIP> it=patternIPList.iterator(); 106 for(; it.hasNext() && matched != EnumEvalResult.TRUE && 107 matched != EnumEvalResult.ERR;) { 108 PatternIP patternIP=it.next(); 109 matched=patternIP.evaluate(addr); 110 } 111 return matched.getRet(type, false); 112 } 113 114 @Override 115 public String toString() { 116 final StringBuilder sb = new StringBuilder(); 117 toString(sb); 118 return sb.toString(); 119 } 120 121 @Override 122 public final void toString(StringBuilder buffer) { 123 buffer.append(super.toString()); 124 } 125}