/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* 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. <p>
*
* <p>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. <p>
*
* <p>The Policy <code>init</code> 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. <p>
*
* <p>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:
* <pre>
* policy = Policy.getPolicy();
* Permissions perms = policy.getPermissions(protectiondomain)
* </pre>
*
* <p>The protection domain contains CodeSource
* object, which encapsulates its codebase (URL) and public key attributes.
* It also contains the principals associated with the domain.
* The Policy object evaluates the global policy in light of who the
* principal is and what the code source is and returns an appropriate
* Permissions object.
*
* @author Roland Schemers
* @author Ram Marti
*
* @since 1.2
*/
public class PolicyParser {
// needs to be public for PolicyTool
// package-private: used by PolicyFile for static policy
// Convenience variables for parsing
"\t[Policy Parser]");
private int lookahead;
private boolean expandProp = false;
throws PropertyExpander.ExpandException
{
}
throws PropertyExpander.ExpandException
{
if (!expandProp) {
return value;
} else {
}
}
/**
* Creates a PolicyParser object.
*/
public PolicyParser() {
}
this();
this.expandProp = expandProp;
}
/**
* Reads a policy configuration into the Policy object using a
* Reader object. <p>
*
* @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.
*/
throws ParsingException, IOException
{
if (!(policy instanceof BufferedReader)) {
}
/**
* 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.resetSyntax();
st.lowerCaseMode(false);
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.
*
*/
if (peek("grant")) {
// could be null if we couldn't expand a property
// only one keystore entry per policy file, others will be
// ignored
// only one keystore passwordURL per policy file, others will be
// ignored
} else {
// error?
}
match(";");
}
("keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore"));
}
}
{
}
{
}
{
}
/**
* Returns the (possibly expanded) keystore location, or null if the
* expansion fails.
*/
try {
}
}
return null;
}
return null;
}
}
return keyStoreType;
}
keyStoreType = type;
}
return keyStoreProvider;
}
}
try {
}
}
return null;
}
return null;
}
this.storePassURL = storePassURL;
}
/**
* 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.
*/
return grantEntries.elements();
}
/**
* write out the policy
*/
{
// write the (unexpanded) keystore entry as the first entry of the
// policy file
if (keyStoreUrlString != null) {
}
if (storePassURL != null) {
}
// write "grant" entries
while (enum_.hasMoreElements()) {
}
}
/**
* parses a keystore entry
*/
match("keystore");
// parse keystore type
if (!peek(",")) {
return; // default type
}
match(",");
if (peek("\"")) {
} else {
}
// parse keystore provider
if (!peek(",")) {
return; // provider optional
}
match(",");
if (peek("\"")) {
} else {
}
}
match("keyStorePasswordURL");
}
/**
* writes the (unexpanded) keystore entry
*/
}
}
/**
* parse a Grant entry
*/
throws ParsingException, IOException
{
GrantEntry e = new GrantEntry();
boolean ignoreEntry = false;
match("grant");
while(!peek("{")) {
if (peekAndMatch("Codebase")) {
throw new ParsingException(
("multiple.Codebase.expressions"));
peekAndMatch(",");
} else if (peekAndMatch("SignedBy")) {
throw new ParsingException(
"multiple.SignedBy.expressions"));
// verify syntax of the aliases
",", true);
int actr = 0;
int cctr = 0;
while (aliases.hasMoreTokens()) {
cctr++;
actr++;
}
throw new ParsingException(
"SignedBy.has.empty.alias"));
peekAndMatch(",");
} else if (peekAndMatch("Principal")) {
if (principals == null) {
}
if (peek("\"")) {
// both the principalClass and principalName
// will be replaced later
} else {
// check for principalClass wildcard
if (peek("*")) {
match("*");
} else {
}
// check for principalName wildcard
if (peek("*")) {
match("*");
} else {
}
// disallow WILDCARD_CLASS && actual name
"has WILDCARD class but no WILDCARD name");
}
throw new ParsingException
("can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name"));
}
}
try {
if (principalClass.equals
("javax.security.auth.x500.X500Principal") &&
// 4702543: X500 names with an EmailAddress
// were encoded incorrectly. construct a new
// X500Principal with correct encoding.
X500Principal p = new X500Principal
principalName = p.getName();
}
// ignore the entire policy entry
// but continue parsing all the info
// so we can get to the next entry
}
ignoreEntry = true;
}
peekAndMatch(",");
} else {
"expected.codeBase.or.SignedBy.or.Principal"));
}
}
match("{");
while(!peek("}")) {
if (peek("Permission")) {
try {
// ignore. The add never happened
}
skipEntry(); // BugId 4219343
}
match(";");
} else {
throw new
"expected.permission.entry"));
}
}
match("}");
try {
// For backward compatibility with 1.4
}
int es;
} else {
// expand the system property "java.ext.dirs",
// parse it into its path components,
// and then create a grant entry for each component
"expanded java.ext.dirs path:\n\t\t" +
extDirs[i]);
}
}
}
ignoreEntry = true;
}
}
}
return null;
}
return (ignoreEntry == true) ? null : e;
}
/**
* parse a Permission entry
*/
{
PermissionEntry e = new PermissionEntry();
// Permission
match("Permission");
if (peek("\"")) {
// Permission name
}
if (!peek(",")) {
return e;
}
match(",");
if (peek("\"")) {
if (!peek(",")) {
return e;
}
match(",");
}
if (peekAndMatch("SignedBy")) {
}
return e;
}
// package-private: used by PolicyFile for static policy
if (s != null) {
for (int i = 0; i < count; i++) {
(file.getAbsolutePath());
}
}
}
return dirs;
}
throws ParsingException, IOException
{
return true;
} else {
return false;
}
}
boolean found = false;
switch (lookahead) {
case StreamTokenizer.TT_WORD:
found = true;
break;
case ',':
found = true;
break;
case '{':
found = true;
break;
case '}':
found = true;
break;
case '"':
found = true;
break;
case '*':
found = true;
break;
default:
}
return found;
}
throws ParsingException, IOException
{
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
case StreamTokenizer.TT_EOF:
("expected.expect.read.end.of.file."));
case StreamTokenizer.TT_WORD:
} else {
}
break;
case '"':
} else {
}
break;
case ',':
else
break;
case '{':
else
break;
case '}':
else
break;
case ';':
else
break;
case '*':
else
break;
default:
}
return value;
}
/**
* skip all tokens for this entry leaving the delimiter ";"
* in the stream.
*/
while(lookahead != ';') {
switch (lookahead) {
case StreamTokenizer.TT_NUMBER:
case StreamTokenizer.TT_EOF:
("expected.read.end.of.file."));
default:
}
}
}
/**
* Each grant entry in the policy configuration file is
* represented by a
* GrantEntry object. <p>
*
* <p>
* For example, the entry
* <pre>
* grant signedBy "Duke" {
* permission java.io.FilePermission "/tmp", "read,write";
* };
*
* </pre>
* is represented internally
* <pre>
*
* pe = new PermissionEntry("java.io.FilePermission",
* "/tmp", "read,write");
*
* ge = new GrantEntry("Duke", null);
*
* ge.add(pe);
*
* </pre>
*
* @author Roland Schemers
*
* version 1.19, 05/21/98
*/
public static class GrantEntry {
public GrantEntry() {
}
}
{
}
{
}
{
}
{
}
{
}
/**
* Enumerate all the permission entries in this GrantEntry.
*/
return permissionEntries.elements();
}
}
}
}
}
while (enum_.hasMoreElements()) {
}
}
return ge;
}
}
/**
* Principal info (class and name) in a grant entry
*/
public static class PrincipalEntry {
/**
* A PrincipalEntry consists of the <code>Principal</code>
* class and <code>Principal</code> name.
*
* <p>
*
* @param principalClass the <code>Principal</code> class. <p>
*
* @param principalName the <code>Principal</code> name. <p>
*/
"null.principalClass.or.principalName"));
this.principalClass = principalClass;
this.principalName = principalName;
}
return principalClass;
}
return principalName;
}
return "*";
return "";
}
else return principalClass;
}
return getDisplayName(false);
}
return "*";
}
else {
else return principalName;
}
}
} else {
return getDisplayName();
}
}
/**
* Test for equality between the specified object and this object.
* Two PrincipalEntries are equal if their PrincipalClass and
* PrincipalName values are equal.
*
* <p>
*
* @param obj the object to test for equality with this object.
*
* @return true if the objects are equal, false otherwise.
*/
if (this == obj)
return true;
if (!(obj instanceof PrincipalEntry))
return false;
return true;
}
return false;
}
/**
* Return a hashcode for this <code>PrincipalEntry</code>.
*
* <p>
*
* @return a hashcode for this <code>PrincipalEntry</code>.
*/
public int hashCode() {
return principalClass.hashCode();
}
getDisplayName(true));
}
}
/**
* Each permission entry in the policy configuration file is
* represented by a
* PermissionEntry object. <p>
*
* <p>
* For example, the entry
* <pre>
* permission java.io.FilePermission "/tmp", "read,write";
* </pre>
* is represented internally
* <pre>
*
* pe = new PermissionEntry("java.io.FilePermission",
* "/tmp", "read,write");
* </pre>
*
* @author Roland Schemers
*
* version 1.19, 05/21/98
*/
public static class PermissionEntry {
public PermissionEntry() {
}
this.permission = permission;
}
/**
* Calculates a hash code value for the object. Objects
* which are equal will also have the same hashcode.
*/
public int hashCode() {
return retval;
}
if (obj == this)
return true;
if (! (obj instanceof PermissionEntry))
return false;
if (this.permission == null) {
} else {
}
} else {
}
} else {
}
} else {
}
// everything matched -- the 2 objects are equal
return true;
}
// ATTENTION: regex with double escaping,
// the normal forms look like:
// $name =~ s/\\/\\\\/g; and
// $name =~ s/\"/\\\"/g;
// and then in a java string, it's escaped again
}
}
}
}
}
/**
* 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.
*/
super(msg);
i18nMessage = msg;
}
}
("line.number.expected.expect.found.actual."));
}
return i18nMessage;
}
}
try {
} finally {
}
}
}
}
}