001/*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: ISSecurityPermission.java,v 1.4 2008/08/19 19:14:56 veiming Exp $
026 *
027 * Portions Copyrighted 2015 ForgeRock AS.
028 */
029
030package com.sun.identity.security;
031
032import java.security.Permission;
033import java.util.HashSet;
034import java.util.Iterator;
035import java.util.Random;
036import java.util.Set;
037import java.util.StringTokenizer;
038
039/**
040 * This class <code>ISSecurityPermission</code> is used to protect the Access
041 * Manager resources which should be accessed only by trusted application. The
042 * resources this Permission is used to protect are: OpenAM
043 * administrator DN and password, and access to the encryption and decryption
044 * methods used to encrypt all passwords in OpenAM services. The
045 * supported permissions is <code>"access"</code> and supported actions are
046 * <code>"adminpassword"</code> and <code>"crypt"</code>. So in the Java
047 * security policy file which will define the security options to grant this
048 * permission to code bases, it should be done as below:
049 * 
050 * <pre>
051 * grant codeBase "file:{directory where jars are located}/-" {
052 * com.sun.identity.security.ISSecurityPermission "access",
053 * "adminpassword,crypt"; };
054 *</pre>
055 * 
056 * Note: The property <code>com.sun.identity.security.checkcaller</code>
057 * should be set to true in <code>AMConfig.properties</code> file to enable the
058 * Java security permissions check.
059 *
060 * @supported.all.api
061 */
062public class ISSecurityPermission extends Permission {
063    private static Random rnd = new Random();
064
065    private String perm;
066
067    private Set actions = new HashSet();
068
069    private int hashCode;
070
071    /**
072     * Constructs <code>ISSecurityPermission</code> object.
073     * 
074     * @param access
075     *            Has to be string "access"
076     * @param action
077     *            Can be <code>adminpassword</code> or <code>crypt</code>.
078     */
079    public ISSecurityPermission(String access, String action) {
080        super(access);
081        perm = access;
082        this.actions = convertActionStringToSet(action);
083        hashCode = rnd.nextInt();
084    }
085
086    /**
087     * Constructs <code>ISSecurityPermission</code> object. This constructor
088     * sets the action to <code>"adminpassword"</code> by default.
089     * 
090     * @param access
091     *            Has to be string "access"
092     */
093    public ISSecurityPermission(String access) {
094        super(access);
095        perm = access;
096        actions = convertActionStringToSet("adminpassword");
097        hashCode = rnd.nextInt();
098    }
099
100    /**
101     * This method checks to see if this instance of
102     * <code>ISSecurityPermission</code> implies the Permission being passed
103     * as the argument. For more information on this, see the Javadocs of
104     * <code>java.security.Permission</code>
105     * 
106     * @param p
107     *            Instance of
108     *            <code>com.sun.identity.security.ISSecurityPermission</code>
109     * @return true if this instance of <code>ISSecurityPermission</code>
110     *         implies the actions of the argument p. False otherwise
111     *         <code>java.security.Permission</code>
112     */
113    public boolean implies(Permission p) {
114        if (!(p instanceof ISSecurityPermission)) {
115            return false;
116        }
117        Set pActions = convertActionStringToSet(p.getActions());
118        // Action "crypt" is implied by the action "adminpassword"
119        if (actions.contains("adminpassword")
120                && (pActions.contains("adminpassword") || pActions
121                        .contains("crypt"))) {
122            return true;
123        } else {
124            if (pActions.contains("crypt") && actions.contains("crypt")) {
125                return true;
126            }
127        }
128        return false;
129    }
130
131    /**
132     * Returns hash code for this object.
133     * 
134     * @see java.security.Permission#hashCode()
135     * @return hash code representing this object
136     */
137    public int hashCode() {
138        return hashCode;
139    }
140
141    /**
142     * Returns true if this object is equals to <code>o</code>.
143     * 
144     * @param o
145     *            object fro comparison.
146     * @return true if both object are similar.
147     */
148    public boolean equals(Object o) {
149        if (o instanceof ISSecurityPermission) {
150            ISSecurityPermission p = (ISSecurityPermission) o;
151            if (p.hashCode() == hashCode) {
152                return true;
153            }
154        }
155        return false;
156    }
157
158    /**
159     * @see java.security.Permission#getActions()
160     * @return String representation of actions supported by
161     *         <code>ISSecurityPermission</code>
162     */
163    public String getActions() {
164        return convertSetToActionString(actions);
165    }
166
167    private Set convertActionStringToSet(String ac) {
168        StringTokenizer tzer = new StringTokenizer(ac, ",");
169        Set res = new HashSet();
170        while (tzer.hasMoreTokens()) {
171            String tmp = tzer.nextToken();
172            res.add(tmp);
173        }
174        return res;
175    }
176
177    private String convertSetToActionString(Set a) {
178        StringBuffer sb = new StringBuffer();
179        Iterator it = a.iterator();
180        while (it.hasNext()) {
181            String t = (String) it.next();
182            sb.append(t).append(",");
183        }
184        String s = sb.toString();
185        int lastComma = s.lastIndexOf(",");
186        return s.substring(0, lastComma);
187    }
188}