/* * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.security.auth; import java.io.*; import java.lang.RuntimePermission; import java.net.MalformedURLException; import java.net.SocketPermission; import java.net.URL; import java.security.GeneralSecurityException; import java.text.MessageFormat; import java.util.Enumeration; import java.util.Hashtable; import java.util.LinkedList; import java.util.ListIterator; import java.util.Vector; import java.util.StringTokenizer; import sun.security.util.PropertyExpander; /** * The policy for a Java runtime (specifying * which permissions are available for code from various principals) * is represented as a separate * persistent configuration. The configuration may be stored as a * flat ASCII file, as a serialized binary file of * the Policy class, or as a database.
* *
The Java runtime creates one global Policy object, which is used to * represent the static policy configuration file. It is consulted by * a ProtectionDomain when the protection domain initializes its set of * permissions.
* *
The Policy init
method parses the policy
* configuration file, and then
* populates the Policy object. The Policy object is agnostic in that
* it is not involved in making policy decisions. It is merely the
* Java runtime representation of the persistent policy configuration
* file.
* *
When a protection domain needs to initialize its set of * permissions, it executes code such as the following * to ask the global Policy object to populate a * Permissions object with the appropriate permissions: *
* policy = Policy.getPolicy(); * Permissions perms = policy.getPermissions(MyCodeSource) ** *
The protection domain passes in a CodeSource
* object, which encapsulates its codebase (URL) and public key attributes.
* The Policy object evaluates the global policy in light of who the
* principal is and returns an appropriate Permissions object.
*
* @deprecated As of JDK 1.4, replaced by
* {@link sun.security.provider.PolicyParser}.
* This class is entirely deprecated.
*
* @author Roland Schemers
*
* @since 1.2
*/
@Deprecated
class PolicyParser {
private static final java.util.ResourceBundle rb =
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction
*
* @param policy the policy Reader object.
*
* @exception ParsingException if the policy configuration contains
* a syntax error.
*
* @exception IOException if an error occurs while reading the policy
* configuration.
*/
public void read(Reader policy)
throws ParsingException, IOException
{
if (!(policy instanceof BufferedReader)) {
policy = new BufferedReader(policy);
}
/**
* Configure the stream tokenizer:
* Recognize strings between "..."
* Don't convert words to lowercase
* Recognize both C-style and C++-style comments
* Treat end-of-line as white space, not as a token
*/
st = new StreamTokenizer(policy);
st.resetSyntax();
st.wordChars('a', 'z');
st.wordChars('A', 'Z');
st.wordChars('.', '.');
st.wordChars('0', '9');
st.wordChars('_', '_');
st.wordChars('$', '$');
st.wordChars(128 + 32, 255);
st.whitespaceChars(0, ' ');
st.commentChar('/');
st.quoteChar('\'');
st.quoteChar('"');
st.lowerCaseMode(false);
st.ordinaryChar('/');
st.slashSlashComments(true);
st.slashStarComments(true);
/**
* The main parsing loop. The loop is executed once
* for each entry in the config file. The entries
* are delimited by semicolons. Once we've read in
* the information for an entry, go ahead and try to
* add it to the policy vector.
*
*/
lookahead = st.nextToken();
while (lookahead != StreamTokenizer.TT_EOF) {
if (peek("grant")) {
GrantEntry ge = parseGrantEntry();
// could be null if we couldn't expand a property
if (ge != null)
add(ge);
} else if (peek("keystore") && keyStoreUrlString==null) {
// only one keystore entry per policy file, others will be
// ignored
parseKeyStoreEntry();
} else {
// error?
}
match(";");
}
}
public void add(GrantEntry ge)
{
grantEntries.addElement(ge);
}
public void replace(GrantEntry origGe, GrantEntry newGe)
{
grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe));
}
public boolean remove(GrantEntry ge)
{
return grantEntries.removeElement(ge);
}
/**
* Returns the (possibly expanded) keystore location, or null if the
* expansion fails.
*/
public String getKeyStoreUrl() {
try {
if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) {
return expand(keyStoreUrlString).replace(File.separatorChar,
'/');
}
} catch (PropertyExpander.ExpandException peee) {
return null;
}
return null;
}
public void setKeyStoreUrl(String url) {
keyStoreUrlString = url;
}
public String getKeyStoreType() {
return keyStoreType;
}
public void setKeyStoreType(String type) {
keyStoreType = type;
}
/**
* Enumerate all the entries in the global policy object.
* This method is used by policy admin tools. The tools
* should use the Enumeration methods on the returned object
* to fetch the elements sequentially.
*/
public Enumeration
*
*
* For example, the entry
*
*
* @param principalClass the
*
* @param principalName the
*/
public PrincipalEntry(String principalClass, String principalName) {
if (principalClass == null || principalName == null)
throw new NullPointerException
("null principalClass or principalName");
this.principalClass = principalClass;
this.principalName = principalName;
}
/**
* Test for equality between the specified object and this object.
* Two PrincipalEntries are equal if their PrincipalClass and
* PrincipalName values are equal.
*
*
*
* @param obj the object to test for equality with this object.
*
* @return true if the objects are equal, false otherwise.
*/
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof PrincipalEntry))
return false;
PrincipalEntry that = (PrincipalEntry)obj;
if (this.principalClass.equals(that.principalClass) &&
this.principalName.equals(that.principalName)) {
return true;
}
return false;
}
/**
* Return a hashcode for this
*
* @return a hashcode for this
*
*
* For example, the entry
*
* grant signedBy "Duke" {
* permission java.io.FilePermission "/tmp", "read,write";
* };
*
*
* is represented internally
*
*
* pe = new PermissionEntry("java.io.FilePermission",
* "/tmp", "read,write");
*
* ge = new GrantEntry("Duke", null);
*
* ge.add(pe);
*
*
*
* @author Roland Schemers
*
* version 1.19, 05/21/98
*/
static class GrantEntry {
public String signedBy;
public String codeBase;
public LinkedListPrincipal
* class and Principal
name.
*
* Principal
class. Principal
name. PrincipalEntry
.
*
* PrincipalEntry
.
*/
public int hashCode() {
return principalClass.hashCode();
}
}
/**
* Each permission entry in the policy configuration file is
* represented by a
* PermissionEntry object.
* permission java.io.FilePermission "/tmp", "read,write";
*
* is represented internally
*
*
* pe = new PermissionEntry("java.io.FilePermission",
* "/tmp", "read,write");
*
*
* @author Roland Schemers
*
* version 1.19, 05/21/98
*/
static class PermissionEntry {
public String permission;
public String name;
public String action;
public String signedBy;
public PermissionEntry() {
}
public PermissionEntry(String permission,
String name,
String action) {
this.permission = permission;
this.name = name;
this.action = action;
}
/**
* Calculates a hash code value for the object. Objects
* which are equal will also have the same hashcode.
*/
public int hashCode() {
int retval = permission.hashCode();
if (name != null) retval ^= name.hashCode();
if (action != null) retval ^= action.hashCode();
return retval;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (! (obj instanceof PermissionEntry))
return false;
PermissionEntry that = (PermissionEntry) obj;
if (this.permission == null) {
if (that.permission != null) return false;
} else {
if (!this.permission.equals(that.permission)) return false;
}
if (this.name == null) {
if (that.name != null) return false;
} else {
if (!this.name.equals(that.name)) return false;
}
if (this.action == null) {
if (that.action != null) return false;
} else {
if (!this.action.equals(that.action)) return false;
}
if (this.signedBy == null) {
if (that.signedBy != null) return false;
} else {
if (!this.signedBy.equals(that.signedBy)) return false;
}
// everything matched -- the 2 objects are equal
return true;
}
public void write(PrintWriter out) {
out.print("permission ");
out.print(permission);
if (name != null) {
out.print(" \"");
// have to add escape chars for quotes
if (name.indexOf("\"") != -1) {
int numQuotes = 0;
char[] chars = name.toCharArray();
// count the number of quote chars
for (int i = 0; i < chars.length; i++) {
if (chars[i] == '"')
numQuotes++;
}
// now, add an escape char before each quote
char[] newChars = new char[chars.length + numQuotes];
for (int i = 0, j = 0; i < chars.length; i++) {
if (chars[i] != '"') {
newChars[j++] = chars[i];
} else {
newChars[j++] = '\\';
newChars[j++] = chars[i];
}
}
name = new String(newChars);
}
out.print(name);
out.print('"');
}
if (action != null) {
out.print(", \"");
out.print(action);
out.print('"');
}
if (signedBy != null) {
out.print(", signedBy \"");
out.print(signedBy);
out.print('"');
}
out.println(";");
}
}
static class ParsingException extends GeneralSecurityException {
private static final long serialVersionUID = 8240970523155877400L;
/**
* Constructs a ParsingException with the specified
* detail message. A detail message is a String that describes
* this particular exception, which may, for example, specify which
* algorithm is not available.
*
* @param msg the detail message.
*/
public ParsingException(String msg) {
super(msg);
}
public ParsingException(int line, String msg) {
super(rb.getString("line.") + line + rb.getString("COLON") + msg);
}
public ParsingException(int line, String expect, String actual) {
super(rb.getString("line.") + line + rb.getString(".expected.") +
expect + rb.getString(".found.") + actual +
rb.getString("QUOTE"));
}
}
public static void main(String arg[]) throws Exception {
PolicyParser pp = new PolicyParser(true);
pp.read(new FileReader(arg[0]));
FileWriter fr = new FileWriter(arg[1]);
pp.write(fr);
fr.close();
}
}