History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/security/auth/PolicyParser.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/security/auth/PolicyParser.java+964−0
@@ -0,0 +1,964 @@
1+/*
2+ * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.security.auth;
27+
28+import java.io.*;
29+import java.lang.RuntimePermission;
30+import java.net.MalformedURLException;
31+import java.net.SocketPermission;
32+import java.net.URL;
33+import java.security.GeneralSecurityException;
34+import java.text.MessageFormat;
35+import java.util.Enumeration;
36+import java.util.Hashtable;
37+import java.util.LinkedList;
38+import java.util.ListIterator;
39+import java.util.Vector;
40+import java.util.StringTokenizer;
41+import sun.security.util.PropertyExpander;
42+
43+/**
44+ * The policy for a Java runtime (specifying
45+ * which permissions are available for code from various principals)
46+ * is represented as a separate
47+ * persistent configuration. The configuration may be stored as a
48+ * flat ASCII file, as a serialized binary file of
49+ * the Policy class, or as a database. <p>
50+ *
51+ * <p>The Java runtime creates one global Policy object, which is used to
52+ * represent the static policy configuration file. It is consulted by
53+ * a ProtectionDomain when the protection domain initializes its set of
54+ * permissions. <p>
55+ *
56+ * <p>The Policy <code>init</code> method parses the policy
57+ * configuration file, and then
58+ * populates the Policy object. The Policy object is agnostic in that
59+ * it is not involved in making policy decisions. It is merely the
60+ * Java runtime representation of the persistent policy configuration
61+ * file. <p>
62+ *
63+ * <p>When a protection domain needs to initialize its set of
64+ * permissions, it executes code such as the following
65+ * to ask the global Policy object to populate a
66+ * Permissions object with the appropriate permissions:
67+ * <pre>
68+ * policy = Policy.getPolicy();
69+ * Permissions perms = policy.getPermissions(MyCodeSource)
70+ * </pre>
71+ *
72+ * <p>The protection domain passes in a CodeSource
73+ * object, which encapsulates its codebase (URL) and public key attributes.
74+ * The Policy object evaluates the global policy in light of who the
75+ * principal is and returns an appropriate Permissions object.
76+ *
77+ * @deprecated As of JDK&nbsp;1.4, replaced by
78+ * {@link sun.security.provider.PolicyParser}.
79+ * This class is entirely deprecated.
80+ *
81+ * @author Roland Schemers
82+ *
83+ * @since 1.2
84+ */
85+@Deprecated
86+class PolicyParser {
87+
88+ private static final java.util.ResourceBundle rb =
89+ java.security.AccessController.doPrivileged
90+ (new java.security.PrivilegedAction<java.util.ResourceBundle>() {
91+ public java.util.ResourceBundle run() {
92+ return (java.util.ResourceBundle.getBundle
93+ ("sun.security.util.AuthResources"));
94+ }
95+ });
96+
97+ private Vector<GrantEntry> grantEntries;
98+
99+ // Convenience variables for parsing
100+ private static final sun.security.util.Debug debug =
101+ sun.security.util.Debug.getInstance("parser", "\t[Auth Policy Parser]");
102+ private StreamTokenizer st;
103+ private int lookahead;
104+ private int linenum;
105+ private boolean expandProp = false;
106+ private String keyStoreUrlString = null; // unexpanded
107+ private String keyStoreType = null;
108+
109+ private String expand(String value)
110+ throws PropertyExpander.ExpandException
111+ {
112+ if (expandProp)
113+ return PropertyExpander.expand(value);
114+ else
115+ return value;
116+ }
117+ /**
118+ * Creates a PolicyParser object.
119+ */
120+
121+ public PolicyParser() {
122+ grantEntries = new Vector<GrantEntry>();
123+ }
124+
125+
126+ public PolicyParser(boolean expandProp) {
127+ this();
128+ this.expandProp = expandProp;
129+ }
130+
131+ /**
132+ * Reads a policy configuration into the Policy object using a
133+ * Reader object. <p>
134+ *
135+ * @param policy the policy Reader object.
136+ *
137+ * @exception ParsingException if the policy configuration contains
138+ * a syntax error.
139+ *
140+ * @exception IOException if an error occurs while reading the policy
141+ * configuration.
142+ */
143+
144+ public void read(Reader policy)
145+ throws ParsingException, IOException
146+ {
147+ if (!(policy instanceof BufferedReader)) {
148+ policy = new BufferedReader(policy);
149+ }
150+
151+ /**
152+ * Configure the stream tokenizer:
153+ * Recognize strings between "..."
154+ * Don't convert words to lowercase
155+ * Recognize both C-style and C++-style comments
156+ * Treat end-of-line as white space, not as a token
157+ */
158+ st = new StreamTokenizer(policy);
159+
160+ st.resetSyntax();
161+ st.wordChars('a', 'z');
162+ st.wordChars('A', 'Z');
163+ st.wordChars('.', '.');
164+ st.wordChars('0', '9');
165+ st.wordChars('_', '_');
166+ st.wordChars('$', '$');
167+ st.wordChars(128 + 32, 255);
168+ st.whitespaceChars(0, ' ');
169+ st.commentChar('/');
170+ st.quoteChar('\'');
171+ st.quoteChar('"');
172+ st.lowerCaseMode(false);
173+ st.ordinaryChar('/');
174+ st.slashSlashComments(true);
175+ st.slashStarComments(true);
176+
177+ /**
178+ * The main parsing loop. The loop is executed once
179+ * for each entry in the config file. The entries
180+ * are delimited by semicolons. Once we've read in
181+ * the information for an entry, go ahead and try to
182+ * add it to the policy vector.
183+ *
184+ */
185+
186+ lookahead = st.nextToken();
187+ while (lookahead != StreamTokenizer.TT_EOF) {
188+ if (peek("grant")) {
189+ GrantEntry ge = parseGrantEntry();
190+ // could be null if we couldn't expand a property
191+ if (ge != null)
192+ add(ge);
193+ } else if (peek("keystore") && keyStoreUrlString==null) {
194+ // only one keystore entry per policy file, others will be
195+ // ignored
196+ parseKeyStoreEntry();
197+ } else {
198+ // error?
199+ }
200+ match(";");
201+ }
202+ }
203+
204+ public void add(GrantEntry ge)
205+ {
206+ grantEntries.addElement(ge);
207+ }
208+
209+ public void replace(GrantEntry origGe, GrantEntry newGe)
210+ {
211+ grantEntries.setElementAt(newGe, grantEntries.indexOf(origGe));
212+ }
213+
214+ public boolean remove(GrantEntry ge)
215+ {
216+ return grantEntries.removeElement(ge);
217+ }
218+
219+ /**
220+ * Returns the (possibly expanded) keystore location, or null if the
221+ * expansion fails.
222+ */
223+ public String getKeyStoreUrl() {
224+ try {
225+ if (keyStoreUrlString!=null && keyStoreUrlString.length()!=0) {
226+ return expand(keyStoreUrlString).replace(File.separatorChar,
227+ '/');
228+ }
229+ } catch (PropertyExpander.ExpandException peee) {
230+ return null;
231+ }
232+ return null;
233+ }
234+
235+ public void setKeyStoreUrl(String url) {
236+ keyStoreUrlString = url;
237+ }
238+
239+ public String getKeyStoreType() {
240+ return keyStoreType;
241+ }
242+
243+ public void setKeyStoreType(String type) {
244+ keyStoreType = type;
245+ }
246+
247+ /**
248+ * Enumerate all the entries in the global policy object.
249+ * This method is used by policy admin tools. The tools
250+ * should use the Enumeration methods on the returned object
251+ * to fetch the elements sequentially.
252+ */
253+ public Enumeration<GrantEntry> grantElements(){
254+ return grantEntries.elements();
255+ }
256+
257+ /**
258+ * write out the policy
259+ */
260+
261+ public void write(Writer policy)
262+ {
263+ PrintWriter out = new PrintWriter(new BufferedWriter(policy));
264+
265+ Enumeration<GrantEntry> enum_ = grantElements();
266+
267+ out.println("/* AUTOMATICALLY GENERATED ON "+
268+ (new java.util.Date()) + "*/");
269+ out.println("/* DO NOT EDIT */");
270+ out.println();
271+
272+ // write the (unexpanded) keystore entry as the first entry of the
273+ // policy file
274+ if (keyStoreUrlString != null) {
275+ writeKeyStoreEntry(out);
276+ }
277+
278+ // write "grant" entries
279+ while (enum_.hasMoreElements()) {
280+ GrantEntry ge = enum_.nextElement();
281+ ge.write(out);
282+ out.println();
283+ }
284+ out.flush();
285+ }
286+
287+ /**
288+ * parses a keystore entry
289+ */
290+ private void parseKeyStoreEntry() throws ParsingException, IOException {
291+ match("keystore");
292+ keyStoreUrlString = match("quoted string");
293+
294+ // parse keystore type
295+ if (!peek(",")) {
296+ return; // default type
297+ }
298+ match(",");
299+
300+ if (peek("\"")) {
301+ keyStoreType = match("quoted string");
302+ } else {
303+ throw new ParsingException(st.lineno(),
304+ rb.getString("expected.keystore.type"));
305+ }
306+ }
307+
308+ /**
309+ * writes the (unexpanded) keystore entry
310+ */
311+ private void writeKeyStoreEntry(PrintWriter out) {
312+ out.print("keystore \"");
313+ out.print(keyStoreUrlString);
314+ out.print('"');
315+ if (keyStoreType != null && keyStoreType.length() > 0)
316+ out.print(", \"" + keyStoreType + "\"");
317+ out.println(";");
318+ out.println();
319+ }
320+
321+ /**
322+ * parse a Grant entry
323+ */
324+ private GrantEntry parseGrantEntry()
325+ throws ParsingException, IOException
326+ {
327+ GrantEntry e = new GrantEntry();
328+ LinkedList<PrincipalEntry> principals = null;
329+ boolean ignoreEntry = false;
330+
331+ match("grant");
332+
333+ while(!peek("{")) {
334+
335+ if (peekAndMatch("Codebase")) {
336+ e.codeBase = match("quoted string");
337+ peekAndMatch(",");
338+ } else if (peekAndMatch("SignedBy")) {
339+ e.signedBy = match("quoted string");
340+ peekAndMatch(",");
341+ } else if (peekAndMatch("Principal")) {
342+ if (principals == null) {
343+ principals = new LinkedList<PrincipalEntry>();
344+ }
345+
346+ // check for principalClass wildcard
347+ String principalClass;
348+ if (peek("*")) {
349+ match("*");
350+ principalClass = PrincipalEntry.WILDCARD_CLASS;
351+ } else {
352+ principalClass = match("principal type");
353+ }
354+
355+ // check for principalName wildcard
356+ String principalName;
357+ if (peek("*")) {
358+ match("*");
359+ principalName = PrincipalEntry.WILDCARD_NAME;
360+ } else {
361+ principalName = match("quoted string");
362+ }
363+
364+ // disallow WILDCARD_CLASS && actual name
365+ if (principalClass.equals(PrincipalEntry.WILDCARD_CLASS) &&
366+ !principalName.equals(PrincipalEntry.WILDCARD_NAME)) {
367+ if (debug != null)
368+ debug.println("disallowing principal that has " +
369+ "WILDCARD class but no WILDCARD name");
370+ throw new ParsingException
371+ (st.lineno(),
372+ rb.getString("can.not.specify.Principal.with.a." +
373+ "wildcard.class.without.a.wildcard.name"));
374+ }
375+
376+ try {
377+ principalName = expand(principalName);
378+ principals.add
379+ (new PrincipalEntry(principalClass, principalName));
380+ } catch (PropertyExpander.ExpandException peee) {
381+ // ignore the entire policy entry
382+ // but continue parsing all the info
383+ // so we can get to the next entry
384+ if (debug != null)
385+ debug.println("principal name expansion failed: " +
386+ principalName);
387+ ignoreEntry = true;
388+ }
389+ peekAndMatch(",");
390+ } else {
391+ throw new
392+ ParsingException(st.lineno(),
393+ rb.getString("expected.codeBase.or.SignedBy"));
394+ }
395+ }
396+
397+ // disallow non principal-based grant entries
398+ if (principals == null) {
399+ throw new ParsingException
400+ (st.lineno(),
401+ rb.getString("only.Principal.based.grant.entries.permitted"));
402+ }
403+
404+ e.principals = principals;
405+ match("{");
406+
407+ while(!peek("}")) {
408+ if (peek("Permission")) {
409+ try {
410+ PermissionEntry pe = parsePermissionEntry();
411+ e.add(pe);
412+ } catch (PropertyExpander.ExpandException peee) {
413+ // ignore. The add never happened
414+ skipEntry(); // BugId 4219343
415+ }
416+ match(";");
417+ } else {
418+ throw new
419+ ParsingException(st.lineno(),
420+ rb.getString("expected.permission.entry"));
421+ }
422+ }
423+ match("}");
424+
425+ try {
426+ if (e.codeBase != null)
427+ e.codeBase = expand(e.codeBase).replace(File.separatorChar, '/');
428+ e.signedBy = expand(e.signedBy);
429+ } catch (PropertyExpander.ExpandException peee) {
430+ return null;
431+ }
432+
433+ return (ignoreEntry == true) ? null : e;
434+ }
435+
436+ /**
437+ * parse a Permission entry
438+ */
439+ private PermissionEntry parsePermissionEntry()
440+ throws ParsingException, IOException, PropertyExpander.ExpandException
441+ {
442+ PermissionEntry e = new PermissionEntry();
443+
444+ // Permission
445+ match("Permission");
446+ e.permission = match("permission type");
447+
448+ if (peek("\"")) {
449+ // Permission name
450+ e.name = expand(match("quoted string"));
451+ }
452+
453+ if (!peek(",")) {
454+ return e;
455+ }
456+ match(",");
457+
458+ if (peek("\"")) {
459+ e.action = expand(match("quoted string"));
460+ if (!peek(",")) {
461+ return e;
462+ }
463+ match(",");
464+ }
465+
466+ if (peekAndMatch("SignedBy")) {
467+ e.signedBy = expand(match("quoted string"));
468+ }
469+ return e;
470+ }
471+
472+ private boolean peekAndMatch(String expect)
473+ throws ParsingException, IOException
474+ {
475+ if (peek(expect)) {
476+ match(expect);
477+ return true;
478+ } else {
479+ return false;
480+ }
481+ }
482+
483+ private boolean peek(String expect) {
484+ boolean found = false;
485+
486+ switch (lookahead) {
487+
488+ case StreamTokenizer.TT_WORD:
489+ if (expect.equalsIgnoreCase(st.sval))
490+ found = true;
491+ break;
492+ case ',':
493+ if (expect.equalsIgnoreCase(","))
494+ found = true;
495+ break;
496+ case '{':
497+ if (expect.equalsIgnoreCase("{"))
498+ found = true;
499+ break;
500+ case '}':
501+ if (expect.equalsIgnoreCase("}"))
502+ found = true;
503+ break;
504+ case '"':
505+ if (expect.equalsIgnoreCase("\""))
506+ found = true;
507+ break;
508+ case '*':
509+ if (expect.equalsIgnoreCase("*"))
510+ found = true;
511+ break;
512+ default:
513+
514+ }
515+ return found;
516+ }
517+
518+ private String match(String expect)
519+ throws ParsingException, IOException
520+ {
521+ String value = null;
522+
523+ switch (lookahead) {
524+ case StreamTokenizer.TT_NUMBER:
525+ throw new ParsingException(st.lineno(), expect,
526+ rb.getString("number.") +
527+ String.valueOf(st.nval));
528+ case StreamTokenizer.TT_EOF:
529+ MessageFormat form = new MessageFormat(
530+ rb.getString("expected.expect.read.end.of.file."));
531+ Object[] source = {expect};
532+ throw new ParsingException(form.format(source));
533+ case StreamTokenizer.TT_WORD:
534+ if (expect.equalsIgnoreCase(st.sval)) {
535+ lookahead = st.nextToken();
536+ } else if (expect.equalsIgnoreCase("permission type")) {
537+ value = st.sval;
538+ lookahead = st.nextToken();
539+ } else if (expect.equalsIgnoreCase("principal type")) {
540+ value = st.sval;
541+ lookahead = st.nextToken();
542+ } else {
543+ throw new ParsingException(st.lineno(), expect, st.sval);
544+ }
545+ break;
546+ case '"':
547+ if (expect.equalsIgnoreCase("quoted string")) {
548+ value = st.sval;
549+ lookahead = st.nextToken();
550+ } else if (expect.equalsIgnoreCase("permission type")) {
551+ value = st.sval;
552+ lookahead = st.nextToken();
553+ } else if (expect.equalsIgnoreCase("principal type")) {
554+ value = st.sval;
555+ lookahead = st.nextToken();
556+ } else {
557+ throw new ParsingException(st.lineno(), expect, st.sval);
558+ }
559+ break;
560+ case ',':
561+ if (expect.equalsIgnoreCase(","))
562+ lookahead = st.nextToken();
563+ else
564+ throw new ParsingException(st.lineno(), expect, ",");
565+ break;
566+ case '{':
567+ if (expect.equalsIgnoreCase("{"))
568+ lookahead = st.nextToken();
569+ else
570+ throw new ParsingException(st.lineno(), expect, "{");
571+ break;
572+ case '}':
573+ if (expect.equalsIgnoreCase("}"))
574+ lookahead = st.nextToken();
575+ else
576+ throw new ParsingException(st.lineno(), expect, "}");
577+ break;
578+ case ';':
579+ if (expect.equalsIgnoreCase(";"))
580+ lookahead = st.nextToken();
581+ else
582+ throw new ParsingException(st.lineno(), expect, ";");
583+ break;
584+ case '*':
585+ if (expect.equalsIgnoreCase("*"))
586+ lookahead = st.nextToken();
587+ else
588+ throw new ParsingException(st.lineno(), expect, "*");
589+ break;
590+ default:
591+ throw new ParsingException(st.lineno(), expect,
592+ new String(new char[] {(char)lookahead}));
593+ }
594+ return value;
595+ }
596+
597+ /**
598+ * skip all tokens for this entry leaving the delimiter ";"
599+ * in the stream.
600+ */
601+ private void skipEntry()
602+ throws ParsingException, IOException
603+ {
604+ while(lookahead != ';') {
605+ switch (lookahead) {
606+ case StreamTokenizer.TT_NUMBER:
607+ throw new ParsingException(st.lineno(), ";",
608+ rb.getString("number.") +
609+ String.valueOf(st.nval));
610+ case StreamTokenizer.TT_EOF:
611+ throw new ParsingException
612+ (rb.getString("expected.read.end.of.file"));
613+ default:
614+ lookahead = st.nextToken();
615+ }
616+ }
617+ }
618+
619+ /**
620+ * Each grant entry in the policy configuration file is
621+ * represented by a
622+ * GrantEntry object. <p>
623+ *
624+ * <p>
625+ * For example, the entry
626+ * <pre>
627+ * grant signedBy "Duke" {
628+ * permission java.io.FilePermission "/tmp", "read,write";
629+ * };
630+ *
631+ * </pre>
632+ * is represented internally
633+ * <pre>
634+ *
635+ * pe = new PermissionEntry("java.io.FilePermission",
636+ * "/tmp", "read,write");
637+ *
638+ * ge = new GrantEntry("Duke", null);
639+ *
640+ * ge.add(pe);
641+ *
642+ * </pre>
643+ *
644+ * @author Roland Schemers
645+ *
646+ * version 1.19, 05/21/98
647+ */
648+
649+ static class GrantEntry {
650+
651+ public String signedBy;
652+ public String codeBase;
653+ public LinkedList<PrincipalEntry> principals;
654+ public Vector<PermissionEntry> permissionEntries;
655+
656+ public GrantEntry() {
657+ permissionEntries = new Vector<PermissionEntry>();
658+ }
659+
660+ public GrantEntry(String signedBy, String codeBase) {
661+ this.codeBase = codeBase;
662+ this.signedBy = signedBy;
663+ permissionEntries = new Vector<PermissionEntry>();
664+ }
665+
666+ public void add(PermissionEntry pe)
667+ {
668+ permissionEntries.addElement(pe);
669+ }
670+
671+ public boolean remove(PermissionEntry pe)
672+ {
673+ return permissionEntries.removeElement(pe);
674+ }
675+
676+ public boolean contains(PermissionEntry pe)
677+ {
678+ return permissionEntries.contains(pe);
679+ }
680+
681+ /**
682+ * Enumerate all the permission entries in this GrantEntry.
683+ */
684+ public Enumeration<PermissionEntry> permissionElements(){
685+ return permissionEntries.elements();
686+ }
687+
688+
689+ public void write(PrintWriter out) {
690+ out.print("grant");
691+ if (signedBy != null) {
692+ out.print(" signedBy \"");
693+ out.print(signedBy);
694+ out.print('"');
695+ if (codeBase != null)
696+ out.print(", ");
697+ }
698+ if (codeBase != null) {
699+ out.print(" codeBase \"");
700+ out.print(codeBase);
701+ out.print('"');
702+ if (principals != null && principals.size() > 0)
703+ out.print(",\n");
704+ }
705+ if (principals != null && principals.size() > 0) {
706+ ListIterator<PrincipalEntry> pli = principals.listIterator();
707+ while (pli.hasNext()) {
708+ out.print("\tPrincipal ");
709+ PrincipalEntry pe = pli.next();
710+ out.print(pe.principalClass +
711+ " \"" + pe.principalName + "\"");
712+ if (pli.hasNext())
713+ out.print(",\n");
714+ }
715+ }
716+ out.println(" {");
717+ Enumeration<PermissionEntry> enum_ = permissionEntries.elements();
718+ while (enum_.hasMoreElements()) {
719+ PermissionEntry pe = enum_.nextElement();
720+ out.write(" ");
721+ pe.write(out);
722+ }
723+ out.println("};");
724+ }
725+
726+ }
727+
728+ /**
729+ * Principal info (class and name) in a grant entry
730+ */
731+ static class PrincipalEntry {
732+
733+ static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS";
734+ static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";
735+
736+ String principalClass;
737+ String principalName;
738+
739+ /**
740+ * A PrincipalEntry consists of the <code>Principal</code>
741+ * class and <code>Principal</code> name.
742+ *
743+ * <p>
744+ *
745+ * @param principalClass the <code>Principal</code> class. <p>
746+ *
747+ * @param principalName the <code>Principal</code> name. <p>
748+ */
749+ public PrincipalEntry(String principalClass, String principalName) {
750+ if (principalClass == null || principalName == null)
751+ throw new NullPointerException
752+ ("null principalClass or principalName");
753+ this.principalClass = principalClass;
754+ this.principalName = principalName;
755+ }
756+
757+ /**
758+ * Test for equality between the specified object and this object.
759+ * Two PrincipalEntries are equal if their PrincipalClass and
760+ * PrincipalName values are equal.
761+ *
762+ * <p>
763+ *
764+ * @param obj the object to test for equality with this object.
765+ *
766+ * @return true if the objects are equal, false otherwise.
767+ */
768+ public boolean equals(Object obj) {
769+ if (this == obj)
770+ return true;
771+
772+ if (!(obj instanceof PrincipalEntry))
773+ return false;
774+
775+ PrincipalEntry that = (PrincipalEntry)obj;
776+ if (this.principalClass.equals(that.principalClass) &&
777+ this.principalName.equals(that.principalName)) {
778+ return true;
779+ }
780+
781+ return false;
782+ }
783+
784+ /**
785+ * Return a hashcode for this <code>PrincipalEntry</code>.
786+ *
787+ * <p>
788+ *
789+ * @return a hashcode for this <code>PrincipalEntry</code>.
790+ */
791+ public int hashCode() {
792+ return principalClass.hashCode();
793+ }
794+ }
795+
796+ /**
797+ * Each permission entry in the policy configuration file is
798+ * represented by a
799+ * PermissionEntry object. <p>
800+ *
801+ * <p>
802+ * For example, the entry
803+ * <pre>
804+ * permission java.io.FilePermission "/tmp", "read,write";
805+ * </pre>
806+ * is represented internally
807+ * <pre>
808+ *
809+ * pe = new PermissionEntry("java.io.FilePermission",
810+ * "/tmp", "read,write");
811+ * </pre>
812+ *
813+ * @author Roland Schemers
814+ *
815+ * version 1.19, 05/21/98
816+ */
817+
818+ static class PermissionEntry {
819+
820+ public String permission;
821+ public String name;
822+ public String action;
823+ public String signedBy;
824+
825+ public PermissionEntry() {
826+ }
827+
828+ public PermissionEntry(String permission,
829+ String name,
830+ String action) {
831+ this.permission = permission;
832+ this.name = name;
833+ this.action = action;
834+ }
835+
836+ /**
837+ * Calculates a hash code value for the object. Objects
838+ * which are equal will also have the same hashcode.
839+ */
840+ public int hashCode() {
841+ int retval = permission.hashCode();
842+ if (name != null) retval ^= name.hashCode();
843+ if (action != null) retval ^= action.hashCode();
844+ return retval;
845+ }
846+
847+ public boolean equals(Object obj) {
848+ if (obj == this)
849+ return true;
850+
851+ if (! (obj instanceof PermissionEntry))
852+ return false;
853+
854+ PermissionEntry that = (PermissionEntry) obj;
855+
856+ if (this.permission == null) {
857+ if (that.permission != null) return false;
858+ } else {
859+ if (!this.permission.equals(that.permission)) return false;
860+ }
861+
862+ if (this.name == null) {
863+ if (that.name != null) return false;
864+ } else {
865+ if (!this.name.equals(that.name)) return false;
866+ }
867+
868+ if (this.action == null) {
869+ if (that.action != null) return false;
870+ } else {
871+ if (!this.action.equals(that.action)) return false;
872+ }
873+
874+ if (this.signedBy == null) {
875+ if (that.signedBy != null) return false;
876+ } else {
877+ if (!this.signedBy.equals(that.signedBy)) return false;
878+ }
879+
880+ // everything matched -- the 2 objects are equal
881+ return true;
882+ }
883+
884+ public void write(PrintWriter out) {
885+ out.print("permission ");
886+ out.print(permission);
887+ if (name != null) {
888+ out.print(" \"");
889+
890+ // have to add escape chars for quotes
891+ if (name.indexOf("\"") != -1) {
892+ int numQuotes = 0;
893+ char[] chars = name.toCharArray();
894+
895+ // count the number of quote chars
896+ for (int i = 0; i < chars.length; i++) {
897+ if (chars[i] == '"')
898+ numQuotes++;
899+ }
900+
901+ // now, add an escape char before each quote
902+ char[] newChars = new char[chars.length + numQuotes];
903+ for (int i = 0, j = 0; i < chars.length; i++) {
904+ if (chars[i] != '"') {
905+ newChars[j++] = chars[i];
906+ } else {
907+ newChars[j++] = '\\';
908+ newChars[j++] = chars[i];
909+ }
910+ }
911+ name = new String(newChars);
912+ }
913+ out.print(name);
914+ out.print('"');
915+ }
916+ if (action != null) {
917+ out.print(", \"");
918+ out.print(action);
919+ out.print('"');
920+ }
921+ if (signedBy != null) {
922+ out.print(", signedBy \"");
923+ out.print(signedBy);
924+ out.print('"');
925+ }
926+ out.println(";");
927+ }
928+ }
929+
930+ static class ParsingException extends GeneralSecurityException {
931+
932+ private static final long serialVersionUID = 8240970523155877400L;
933+
934+ /**
935+ * Constructs a ParsingException with the specified
936+ * detail message. A detail message is a String that describes
937+ * this particular exception, which may, for example, specify which
938+ * algorithm is not available.
939+ *
940+ * @param msg the detail message.
941+ */
942+ public ParsingException(String msg) {
943+ super(msg);
944+ }
945+
946+ public ParsingException(int line, String msg) {
947+ super(rb.getString("line.") + line + rb.getString("COLON") + msg);
948+ }
949+
950+ public ParsingException(int line, String expect, String actual) {
951+ super(rb.getString("line.") + line + rb.getString(".expected.") +
952+ expect + rb.getString(".found.") + actual +
953+ rb.getString("QUOTE"));
954+ }
955+ }
956+
957+ public static void main(String arg[]) throws Exception {
958+ PolicyParser pp = new PolicyParser(true);
959+ pp.read(new FileReader(arg[0]));
960+ FileWriter fr = new FileWriter(arg[1]);
961+ pp.write(fr);
962+ fr.close();
963+ }
964+}