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