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/java/security/UnresolvedPermission.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/security/UnresolvedPermission.java+604−0
@@ -0,0 +1,604 @@
1+/*
2+ * Copyright (c) 1997, 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 java.security;
27+
28+import java.io.IOException;
29+import java.io.ByteArrayInputStream;
30+import java.util.ArrayList;
31+import java.util.Enumeration;
32+import java.util.Hashtable;
33+import java.util.Vector;
34+import java.lang.reflect.*;
35+import java.security.cert.*;
36+
37+/**
38+ * The UnresolvedPermission class is used to hold Permissions that
39+ * were "unresolved" when the Policy was initialized.
40+ * An unresolved permission is one whose actual Permission class
41+ * does not yet exist at the time the Policy is initialized (see below).
42+ *
43+ * <p>The policy for a Java runtime (specifying
44+ * which permissions are available for code from various principals)
45+ * is represented by a Policy object.
46+ * Whenever a Policy is initialized or refreshed, Permission objects of
47+ * appropriate classes are created for all permissions
48+ * allowed by the Policy.
49+ *
50+ * <p>Many permission class types
51+ * referenced by the policy configuration are ones that exist
52+ * locally (i.e., ones that can be found on CLASSPATH).
53+ * Objects for such permissions can be instantiated during
54+ * Policy initialization. For example, it is always possible
55+ * to instantiate a java.io.FilePermission, since the
56+ * FilePermission class is found on the CLASSPATH.
57+ *
58+ * <p>Other permission classes may not yet exist during Policy
59+ * initialization. For example, a referenced permission class may
60+ * be in a JAR file that will later be loaded.
61+ * For each such class, an UnresolvedPermission is instantiated.
62+ * Thus, an UnresolvedPermission is essentially a "placeholder"
63+ * containing information about the permission.
64+ *
65+ * <p>Later, when code calls AccessController.checkPermission
66+ * on a permission of a type that was previously unresolved,
67+ * but whose class has since been loaded, previously-unresolved
68+ * permissions of that type are "resolved". That is,
69+ * for each such UnresolvedPermission, a new object of
70+ * the appropriate class type is instantiated, based on the
71+ * information in the UnresolvedPermission.
72+ *
73+ * <p> To instantiate the new class, UnresolvedPermission assumes
74+ * the class provides a zero, one, and/or two-argument constructor.
75+ * The zero-argument constructor would be used to instantiate
76+ * a permission without a name and without actions.
77+ * A one-arg constructor is assumed to take a <code>String</code>
78+ * name as input, and a two-arg constructor is assumed to take a
79+ * <code>String</code> name and <code>String</code> actions
80+ * as input. UnresolvedPermission may invoke a
81+ * constructor with a <code>null</code> name and/or actions.
82+ * If an appropriate permission constructor is not available,
83+ * the UnresolvedPermission is ignored and the relevant permission
84+ * will not be granted to executing code.
85+ *
86+ * <p> The newly created permission object replaces the
87+ * UnresolvedPermission, which is removed.
88+ *
89+ * <p> Note that the <code>getName</code> method for an
90+ * <code>UnresolvedPermission</code> returns the
91+ * <code>type</code> (class name) for the underlying permission
92+ * that has not been resolved.
93+ *
94+ * @see java.security.Permission
95+ * @see java.security.Permissions
96+ * @see java.security.PermissionCollection
97+ * @see java.security.Policy
98+ *
99+ *
100+ * @author Roland Schemers
101+ */
102+
103+public final class UnresolvedPermission extends Permission
104+implements java.io.Serializable
105+{
106+
107+ private static final long serialVersionUID = -4821973115467008846L;
108+
109+ private static final sun.security.util.Debug debug =
110+ sun.security.util.Debug.getInstance
111+ ("policy,access", "UnresolvedPermission");
112+
113+ /**
114+ * The class name of the Permission class that will be
115+ * created when this unresolved permission is resolved.
116+ *
117+ * @serial
118+ */
119+ private String type;
120+
121+ /**
122+ * The permission name.
123+ *
124+ * @serial
125+ */
126+ private String name;
127+
128+ /**
129+ * The actions of the permission.
130+ *
131+ * @serial
132+ */
133+ private String actions;
134+
135+ private transient java.security.cert.Certificate certs[];
136+
137+ /**
138+ * Creates a new UnresolvedPermission containing the permission
139+ * information needed later to actually create a Permission of the
140+ * specified class, when the permission is resolved.
141+ *
142+ * @param type the class name of the Permission class that will be
143+ * created when this unresolved permission is resolved.
144+ * @param name the name of the permission.
145+ * @param actions the actions of the permission.
146+ * @param certs the certificates the permission's class was signed with.
147+ * This is a list of certificate chains, where each chain is composed of a
148+ * signer certificate and optionally its supporting certificate chain.
149+ * Each chain is ordered bottom-to-top (i.e., with the signer certificate
150+ * first and the (root) certificate authority last). The signer
151+ * certificates are copied from the array. Subsequent changes to
152+ * the array will not affect this UnsolvedPermission.
153+ */
154+ public UnresolvedPermission(String type,
155+ String name,
156+ String actions,
157+ java.security.cert.Certificate certs[])
158+ {
159+ super(type);
160+
161+ if (type == null)
162+ throw new NullPointerException("type can't be null");
163+
164+ this.type = type;
165+ this.name = name;
166+ this.actions = actions;
167+ if (certs != null) {
168+ // Extract the signer certs from the list of certificates.
169+ for (int i=0; i<certs.length; i++) {
170+ if (!(certs[i] instanceof X509Certificate)) {
171+ // there is no concept of signer certs, so we store the
172+ // entire cert array
173+ this.certs = certs.clone();
174+ break;
175+ }
176+ }
177+
178+ if (this.certs == null) {
179+ // Go through the list of certs and see if all the certs are
180+ // signer certs.
181+ int i = 0;
182+ int count = 0;
183+ while (i < certs.length) {
184+ count++;
185+ while (((i+1) < certs.length) &&
186+ ((X509Certificate)certs[i]).getIssuerDN().equals(
187+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
188+ i++;
189+ }
190+ i++;
191+ }
192+ if (count == certs.length) {
193+ // All the certs are signer certs, so we store the entire
194+ // array
195+ this.certs = certs.clone();
196+ }
197+
198+ if (this.certs == null) {
199+ // extract the signer certs
200+ ArrayList<java.security.cert.Certificate> signerCerts =
201+ new ArrayList<>();
202+ i = 0;
203+ while (i < certs.length) {
204+ signerCerts.add(certs[i]);
205+ while (((i+1) < certs.length) &&
206+ ((X509Certificate)certs[i]).getIssuerDN().equals(
207+ ((X509Certificate)certs[i+1]).getSubjectDN())) {
208+ i++;
209+ }
210+ i++;
211+ }
212+ this.certs =
213+ new java.security.cert.Certificate[signerCerts.size()];
214+ signerCerts.toArray(this.certs);
215+ }
216+ }
217+ }
218+ }
219+
220+
221+ private static final Class[] PARAMS0 = { };
222+ private static final Class[] PARAMS1 = { String.class };
223+ private static final Class[] PARAMS2 = { String.class, String.class };
224+
225+ /**
226+ * try and resolve this permission using the class loader of the permission
227+ * that was passed in.
228+ */
229+ Permission resolve(Permission p, java.security.cert.Certificate certs[]) {
230+ if (this.certs != null) {
231+ // if p wasn't signed, we don't have a match
232+ if (certs == null) {
233+ return null;
234+ }
235+
236+ // all certs in this.certs must be present in certs
237+ boolean match;
238+ for (int i = 0; i < this.certs.length; i++) {
239+ match = false;
240+ for (int j = 0; j < certs.length; j++) {
241+ if (this.certs[i].equals(certs[j])) {
242+ match = true;
243+ break;
244+ }
245+ }
246+ if (!match) return null;
247+ }
248+ }
249+ try {
250+ Class pc = p.getClass();
251+
252+ if (name == null && actions == null) {
253+ try {
254+ Constructor c = pc.getConstructor(PARAMS0);
255+ return (Permission)c.newInstance(new Object[] {});
256+ } catch (NoSuchMethodException ne) {
257+ try {
258+ Constructor c = pc.getConstructor(PARAMS1);
259+ return (Permission) c.newInstance(
260+ new Object[] { name});
261+ } catch (NoSuchMethodException ne1) {
262+ Constructor c = pc.getConstructor(PARAMS2);
263+ return (Permission) c.newInstance(
264+ new Object[] { name, actions });
265+ }
266+ }
267+ } else {
268+ if (name != null && actions == null) {
269+ try {
270+ Constructor c = pc.getConstructor(PARAMS1);
271+ return (Permission) c.newInstance(
272+ new Object[] { name});
273+ } catch (NoSuchMethodException ne) {
274+ Constructor c = pc.getConstructor(PARAMS2);
275+ return (Permission) c.newInstance(
276+ new Object[] { name, actions });
277+ }
278+ } else {
279+ Constructor c = pc.getConstructor(PARAMS2);
280+ return (Permission) c.newInstance(
281+ new Object[] { name, actions });
282+ }
283+ }
284+ } catch (NoSuchMethodException nsme) {
285+ if (debug != null ) {
286+ debug.println("NoSuchMethodException:\n could not find " +
287+ "proper constructor for " + type);
288+ nsme.printStackTrace();
289+ }
290+ return null;
291+ } catch (Exception e) {
292+ if (debug != null ) {
293+ debug.println("unable to instantiate " + name);
294+ e.printStackTrace();
295+ }
296+ return null;
297+ }
298+ }
299+
300+ /**
301+ * This method always returns false for unresolved permissions.
302+ * That is, an UnresolvedPermission is never considered to
303+ * imply another permission.
304+ *
305+ * @param p the permission to check against.
306+ *
307+ * @return false.
308+ */
309+ public boolean implies(Permission p) {
310+ return false;
311+ }
312+
313+ /**
314+ * Checks two UnresolvedPermission objects for equality.
315+ * Checks that <i>obj</i> is an UnresolvedPermission, and has
316+ * the same type (class) name, permission name, actions, and
317+ * certificates as this object.
318+ *
319+ * <p> To determine certificate equality, this method only compares
320+ * actual signer certificates. Supporting certificate chains
321+ * are not taken into consideration by this method.
322+ *
323+ * @param obj the object we are testing for equality with this object.
324+ *
325+ * @return true if obj is an UnresolvedPermission, and has the same
326+ * type (class) name, permission name, actions, and
327+ * certificates as this object.
328+ */
329+ public boolean equals(Object obj) {
330+ if (obj == this)
331+ return true;
332+
333+ if (! (obj instanceof UnresolvedPermission))
334+ return false;
335+ UnresolvedPermission that = (UnresolvedPermission) obj;
336+
337+ // check type
338+ if (!this.type.equals(that.type)) {
339+ return false;
340+ }
341+
342+ // check name
343+ if (this.name == null) {
344+ if (that.name != null) {
345+ return false;
346+ }
347+ } else if (!this.name.equals(that.name)) {
348+ return false;
349+ }
350+
351+ // check actions
352+ if (this.actions == null) {
353+ if (that.actions != null) {
354+ return false;
355+ }
356+ } else {
357+ if (!this.actions.equals(that.actions)) {
358+ return false;
359+ }
360+ }
361+
362+ // check certs
363+ if ((this.certs == null && that.certs != null) ||
364+ (this.certs != null && that.certs == null) ||
365+ (this.certs != null && that.certs != null &&
366+ this.certs.length != that.certs.length)) {
367+ return false;
368+ }
369+
370+ int i,j;
371+ boolean match;
372+
373+ for (i = 0; this.certs != null && i < this.certs.length; i++) {
374+ match = false;
375+ for (j = 0; j < that.certs.length; j++) {
376+ if (this.certs[i].equals(that.certs[j])) {
377+ match = true;
378+ break;
379+ }
380+ }
381+ if (!match) return false;
382+ }
383+
384+ for (i = 0; that.certs != null && i < that.certs.length; i++) {
385+ match = false;
386+ for (j = 0; j < this.certs.length; j++) {
387+ if (that.certs[i].equals(this.certs[j])) {
388+ match = true;
389+ break;
390+ }
391+ }
392+ if (!match) return false;
393+ }
394+ return true;
395+ }
396+
397+ /**
398+ * Returns the hash code value for this object.
399+ *
400+ * @return a hash code value for this object.
401+ */
402+
403+ public int hashCode() {
404+ int hash = type.hashCode();
405+ if (name != null)
406+ hash ^= name.hashCode();
407+ if (actions != null)
408+ hash ^= actions.hashCode();
409+ return hash;
410+ }
411+
412+ /**
413+ * Returns the canonical string representation of the actions,
414+ * which currently is the empty string "", since there are no actions for
415+ * an UnresolvedPermission. That is, the actions for the
416+ * permission that will be created when this UnresolvedPermission
417+ * is resolved may be non-null, but an UnresolvedPermission
418+ * itself is never considered to have any actions.
419+ *
420+ * @return the empty string "".
421+ */
422+ public String getActions()
423+ {
424+ return "";
425+ }
426+
427+ /**
428+ * Get the type (class name) of the underlying permission that
429+ * has not been resolved.
430+ *
431+ * @return the type (class name) of the underlying permission that
432+ * has not been resolved
433+ *
434+ * @since 1.5
435+ */
436+ public String getUnresolvedType() {
437+ return type;
438+ }
439+
440+ /**
441+ * Get the target name of the underlying permission that
442+ * has not been resolved.
443+ *
444+ * @return the target name of the underlying permission that
445+ * has not been resolved, or <code>null</code>,
446+ * if there is no targe name
447+ *
448+ * @since 1.5
449+ */
450+ public String getUnresolvedName() {
451+ return name;
452+ }
453+
454+ /**
455+ * Get the actions for the underlying permission that
456+ * has not been resolved.
457+ *
458+ * @return the actions for the underlying permission that
459+ * has not been resolved, or <code>null</code>
460+ * if there are no actions
461+ *
462+ * @since 1.5
463+ */
464+ public String getUnresolvedActions() {
465+ return actions;
466+ }
467+
468+ /**
469+ * Get the signer certificates (without any supporting chain)
470+ * for the underlying permission that has not been resolved.
471+ *
472+ * @return the signer certificates for the underlying permission that
473+ * has not been resolved, or null, if there are no signer certificates.
474+ * Returns a new array each time this method is called.
475+ *
476+ * @since 1.5
477+ */
478+ public java.security.cert.Certificate[] getUnresolvedCerts() {
479+ return (certs == null) ? null : certs.clone();
480+ }
481+
482+ /**
483+ * Returns a string describing this UnresolvedPermission. The convention
484+ * is to specify the class name, the permission name, and the actions, in
485+ * the following format: '(unresolved "ClassName" "name" "actions")'.
486+ *
487+ * @return information about this UnresolvedPermission.
488+ */
489+ public String toString() {
490+ return "(unresolved " + type + " " + name + " " + actions + ")";
491+ }
492+
493+ /**
494+ * Returns a new PermissionCollection object for storing
495+ * UnresolvedPermission objects.
496+ * <p>
497+ * @return a new PermissionCollection object suitable for
498+ * storing UnresolvedPermissions.
499+ */
500+
501+ public PermissionCollection newPermissionCollection() {
502+ return new UnresolvedPermissionCollection();
503+ }
504+
505+ /**
506+ * Writes this object out to a stream (i.e., serializes it).
507+ *
508+ * @serialData An initial <code>String</code> denoting the
509+ * <code>type</code> is followed by a <code>String</code> denoting the
510+ * <code>name</code> is followed by a <code>String</code> denoting the
511+ * <code>actions</code> is followed by an <code>int</code> indicating the
512+ * number of certificates to follow
513+ * (a value of "zero" denotes that there are no certificates associated
514+ * with this object).
515+ * Each certificate is written out starting with a <code>String</code>
516+ * denoting the certificate type, followed by an
517+ * <code>int</code> specifying the length of the certificate encoding,
518+ * followed by the certificate encoding itself which is written out as an
519+ * array of bytes.
520+ */
521+ private void writeObject(java.io.ObjectOutputStream oos)
522+ throws IOException
523+ {
524+ oos.defaultWriteObject();
525+
526+ if (certs==null || certs.length==0) {
527+ oos.writeInt(0);
528+ } else {
529+ // write out the total number of certs
530+ oos.writeInt(certs.length);
531+ // write out each cert, including its type
532+ for (int i=0; i < certs.length; i++) {
533+ java.security.cert.Certificate cert = certs[i];
534+ try {
535+ oos.writeUTF(cert.getType());
536+ byte[] encoded = cert.getEncoded();
537+ oos.writeInt(encoded.length);
538+ oos.write(encoded);
539+ } catch (CertificateEncodingException cee) {
540+ throw new IOException(cee.getMessage());
541+ }
542+ }
543+ }
544+ }
545+
546+ /**
547+ * Restores this object from a stream (i.e., deserializes it).
548+ */
549+ private void readObject(java.io.ObjectInputStream ois)
550+ throws IOException, ClassNotFoundException
551+ {
552+ CertificateFactory cf;
553+ Hashtable<String, CertificateFactory> cfs = null;
554+
555+ ois.defaultReadObject();
556+
557+ if (type == null)
558+ throw new NullPointerException("type can't be null");
559+
560+ // process any new-style certs in the stream (if present)
561+ int size = ois.readInt();
562+ if (size > 0) {
563+ // we know of 3 different cert types: X.509, PGP, SDSI, which
564+ // could all be present in the stream at the same time
565+ cfs = new Hashtable<String, CertificateFactory>(3);
566+ this.certs = new java.security.cert.Certificate[size];
567+ }
568+
569+ for (int i=0; i<size; i++) {
570+ // read the certificate type, and instantiate a certificate
571+ // factory of that type (reuse existing factory if possible)
572+ String certType = ois.readUTF();
573+ if (cfs.containsKey(certType)) {
574+ // reuse certificate factory
575+ cf = cfs.get(certType);
576+ } else {
577+ // create new certificate factory
578+ try {
579+ cf = CertificateFactory.getInstance(certType);
580+ } catch (CertificateException ce) {
581+ throw new ClassNotFoundException
582+ ("Certificate factory for "+certType+" not found");
583+ }
584+ // store the certificate factory so we can reuse it later
585+ cfs.put(certType, cf);
586+ }
587+ // parse the certificate
588+ byte[] encoded=null;
589+ try {
590+ encoded = new byte[ois.readInt()];
591+ } catch (OutOfMemoryError oome) {
592+ throw new IOException("Certificate too big");
593+ }
594+ ois.readFully(encoded);
595+ ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
596+ try {
597+ this.certs[i] = cf.generateCertificate(bais);
598+ } catch (CertificateException ce) {
599+ throw new IOException(ce.getMessage());
600+ }
601+ bais.close();
602+ }
603+ }
604+}