mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
15.43.2014 62b134351917387ee30ed318f06f0dae766e8b31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2013-2014 ForgeRock AS
 */
package org.opends.server.authorization.dseecompat;
import org.forgerock.i18n.LocalizableMessage;
 
import static org.opends.messages.AccessControlMessages.*;
import java.util.regex.Pattern;
import java.util.*;
import java.net.InetAddress;
 
/**
 * This class represents a single ACI's IP bind rule expression. It is possble
 * for that expression to contain several IP addresses to evaluate, so the
 * class contains a list of classes that can evaluate a remote clients IP
 * address for each IP address parsed from the bind rule.
 */
public class IP implements KeywordBindRule {
 
    /**
     * Regular expression used to do a quick check on the characters in a
     * bind rule address. These are all of the valid characters that may
     * appear in an bind rule address part.
     */
    private  static final String ipRegEx =
            "((?i)[\\.{1}[a-f]\\d:\\+{1}\\*/{1}\\t\\[{1}\\]{1}]+(?-i))";
 
    /**
     * List of the pattern classes, one for each address decoded from the bind
     * rule.
     */
    private List<PatternIP> patternIPList=null;
 
    /** The type of the bind rule (!= or =). */
    private EnumBindRuleType type=null;
 
    /**
     * Create a class representing the IP bind rule expressions for this ACI.
     * @param patternIPList A list of PatternIP objects representing the IP
     *                      bind rule expressions decoded from ACI.
     * @param type An enumeration representing the expression type.
     */
    private IP(List<PatternIP> patternIPList, EnumBindRuleType type) {
        this.patternIPList=patternIPList;
        this.type=type;
    }
 
    /**
     * Decodes the provided IP bind rule expression string and returns an
     * IP class the can be used to evaluate remote clients IP addresses.
     *
     * @param expr The expression string from the ACI IP bind rule.
     * @param type An enmumeration representing the expression type.
     * @return  A class that can be used to evaluate remote clients IP
     *          addresses.
     * @throws AciException  If there is a parsing error.
     */
    public static KeywordBindRule decode(String expr, EnumBindRuleType type)
            throws AciException  {
        //Split on the ','.
        String[] ipStrs=expr.split("\\,", -1);
        List<PatternIP> patternIPList= new LinkedList<PatternIP>();
        for (String ipStr : ipStrs) {
            if (!Pattern.matches(ipRegEx, ipStr)) {
                LocalizableMessage message =
                    WARN_ACI_SYNTAX_INVALID_IP_EXPRESSION.get(expr);
                throw new AciException(message);
            }
            PatternIP ipPattern = PatternIP.decode(ipStr);
            patternIPList.add(ipPattern);
        }
        return new IP(patternIPList, type);
    }
 
    /**
     * Perform an evaluation using the provided evaluation context's remote
     * IP address information.
     *
     * @param evalCtx An evaluation context containing the remote clients
     * IP address information.
     *
     * @return An enumeration representing if the address matched.
     */
    public EnumEvalResult evaluate(AciEvalContext evalCtx) {
        InetAddress remoteAddr=evalCtx.getRemoteAddress();
        return evaluate(remoteAddr);
    }
 
    /**
     * Perform an evaluation using the InetAddress.
     *
     * @param addr  The InetAddress to evaluate against PatternIP classes.
     * @return  An enumeration representing if the address matched one
     *          of the patterns.
     */
    EnumEvalResult evaluate(InetAddress addr) {
        EnumEvalResult matched=EnumEvalResult.FALSE;
        Iterator<PatternIP> it=patternIPList.iterator();
        for(; it.hasNext() && matched != EnumEvalResult.TRUE &&
                matched != EnumEvalResult.ERR;) {
            PatternIP patternIP=it.next();
            matched=patternIP.evaluate(addr);
        }
        return matched.getRet(type, false);
    }
 
    /** {@inheritDoc} */
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        toString(sb);
        return sb.toString();
    }
 
    /** {@inheritDoc} */
    @Override
    public final void toString(StringBuilder buffer) {
        buffer.append(super.toString());
    }
 
}