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
26package java.security;
27
28import java.io.IOException;
29import java.io.ByteArrayInputStream;
30import java.util.ArrayList;
31import java.util.Enumeration;
32import java.util.Hashtable;
33import java.util.Vector;
34import java.lang.reflect.*;
35import 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
103public final class UnresolvedPermission extends Permission
104implements 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}