Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/provider/AuthPolicyFile.java
38830 views
1
/*
2
* Copyright (c) 1999, 2013, 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 sun.security.provider;
27
28
import java.io.*;
29
import java.lang.reflect.*;
30
import java.net.URL;
31
import java.util.*;
32
33
import java.security.AccessController;
34
import java.security.CodeSource;
35
import java.security.KeyStore;
36
import java.security.KeyStoreException;
37
import java.security.Permission;
38
import java.security.Permissions;
39
import java.security.PermissionCollection;
40
import java.security.Principal;
41
import java.security.PrivilegedAction;
42
import java.security.UnresolvedPermission;
43
import java.security.Security;
44
import java.security.cert.Certificate;
45
import java.security.cert.X509Certificate;
46
47
import javax.security.auth.Subject;
48
import javax.security.auth.PrivateCredentialPermission;
49
50
import sun.security.provider.PolicyParser.GrantEntry;
51
import sun.security.provider.PolicyParser.PermissionEntry;
52
import sun.security.provider.PolicyParser.PrincipalEntry;
53
import sun.security.util.Debug;
54
import sun.security.util.PolicyUtil;
55
import sun.security.util.PropertyExpander;
56
57
/**
58
* See {@code com.sun.security.auth.PolicyFile} for the class description.
59
* This class is necessary in order to support a default
60
* {@code javax.security.auth.Policy} implementation on the compact1 and
61
* compact2 profiles.
62
*
63
* @deprecated As of JDK 1.4, replaced by
64
* {@code sun.security.provider.PolicyFile}.
65
* This class is entirely deprecated.
66
*/
67
@Deprecated
68
public class AuthPolicyFile extends javax.security.auth.Policy {
69
70
static final ResourceBundle rb =
71
AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
72
@Override public ResourceBundle run() {
73
return (ResourceBundle.getBundle
74
("sun.security.util.AuthResources"));
75
}
76
});
77
78
private static final Debug debug = Debug.getInstance("policy",
79
"\t[Auth Policy]");
80
81
private static final String AUTH_POLICY = "java.security.auth.policy";
82
private static final String SECURITY_MANAGER = "java.security.manager";
83
private static final String AUTH_POLICY_URL = "auth.policy.url.";
84
85
private Vector<PolicyEntry> policyEntries;
86
private Hashtable<Object, Object> aliasMapping;
87
88
private boolean initialized = false;
89
90
private boolean expandProperties = true;
91
private boolean ignoreIdentityScope = true;
92
93
// for use with the reflection API
94
private static final Class<?>[] PARAMS = { String.class, String.class};
95
96
/**
97
* Initializes the Policy object and reads the default policy
98
* configuration file(s) into the Policy object.
99
*/
100
public AuthPolicyFile() {
101
// initialize Policy if either the AUTH_POLICY or
102
// SECURITY_MANAGER properties are set
103
String prop = System.getProperty(AUTH_POLICY);
104
105
if (prop == null) {
106
prop = System.getProperty(SECURITY_MANAGER);
107
}
108
if (prop != null) {
109
init();
110
}
111
}
112
113
private synchronized void init() {
114
if (initialized) {
115
return;
116
}
117
118
policyEntries = new Vector<PolicyEntry>();
119
aliasMapping = new Hashtable<Object, Object>(11);
120
121
initPolicyFile();
122
initialized = true;
123
}
124
125
@Override
126
public synchronized void refresh() {
127
128
java.lang.SecurityManager sm = System.getSecurityManager();
129
if (sm != null) {
130
sm.checkPermission(new javax.security.auth.AuthPermission
131
("refreshPolicy"));
132
}
133
134
// XXX
135
//
136
// 1) if code instantiates PolicyFile directly, then it will need
137
// all the permissions required for the PolicyFile initialization
138
// 2) if code calls Policy.getPolicy, then it simply needs
139
// AuthPermission(getPolicy), and the javax.security.auth.Policy
140
// implementation instantiates PolicyFile in a doPrivileged block
141
// 3) if after instantiating a Policy (either via #1 or #2),
142
// code calls refresh, it simply needs
143
// AuthPermission(refreshPolicy). then PolicyFile wraps
144
// the refresh in a doPrivileged block.
145
initialized = false;
146
AccessController.doPrivileged(new PrivilegedAction<Void>() {
147
@Override public Void run() {
148
init();
149
return null;
150
}
151
});
152
}
153
154
private KeyStore initKeyStore(URL policyUrl, String keyStoreName,
155
String keyStoreType) {
156
if (keyStoreName != null) {
157
try {
158
/*
159
* location of keystore is specified as absolute URL in policy
160
* file, or is relative to URL of policy file
161
*/
162
URL keyStoreUrl = null;
163
try {
164
keyStoreUrl = new URL(keyStoreName);
165
// absolute URL
166
} catch (java.net.MalformedURLException e) {
167
// relative URL
168
keyStoreUrl = new URL(policyUrl, keyStoreName);
169
}
170
171
if (debug != null) {
172
debug.println("reading keystore"+keyStoreUrl);
173
}
174
175
InputStream inStream = new BufferedInputStream(
176
PolicyUtil.getInputStream(keyStoreUrl));
177
178
KeyStore ks;
179
if (keyStoreType != null)
180
ks = KeyStore.getInstance(keyStoreType);
181
else
182
ks = KeyStore.getInstance(KeyStore.getDefaultType());
183
ks.load(inStream, null);
184
inStream.close();
185
return ks;
186
} catch (Exception e) {
187
// ignore, treat it like we have no keystore
188
if (debug != null) {
189
debug.println("Debug info only. No keystore.");
190
e.printStackTrace();
191
}
192
return null;
193
}
194
}
195
return null;
196
}
197
198
private void initPolicyFile() {
199
200
String prop = Security.getProperty("policy.expandProperties");
201
if (prop != null) {
202
expandProperties = prop.equalsIgnoreCase("true");
203
}
204
205
String iscp = Security.getProperty("policy.ignoreIdentityScope");
206
if (iscp != null) {
207
ignoreIdentityScope = iscp.equalsIgnoreCase("true");
208
}
209
210
String allowSys = Security.getProperty("policy.allowSystemProperty");
211
if (allowSys != null && allowSys.equalsIgnoreCase("true")) {
212
String extra_policy = System.getProperty(AUTH_POLICY);
213
if (extra_policy != null) {
214
boolean overrideAll = false;
215
if (extra_policy.startsWith("=")) {
216
overrideAll = true;
217
extra_policy = extra_policy.substring(1);
218
}
219
try {
220
extra_policy = PropertyExpander.expand(extra_policy);
221
URL policyURL;
222
File policyFile = new File(extra_policy);
223
if (policyFile.exists()) {
224
policyURL =
225
new URL("file:" + policyFile.getCanonicalPath());
226
} else {
227
policyURL = new URL(extra_policy);
228
}
229
if (debug != null) {
230
debug.println("reading " + policyURL);
231
}
232
init(policyURL);
233
} catch (Exception e) {
234
// ignore.
235
if (debug != null) {
236
debug.println("caught exception: " + e);
237
}
238
239
}
240
if (overrideAll) {
241
if (debug != null) {
242
debug.println("overriding other policies!");
243
}
244
return;
245
}
246
}
247
}
248
249
int n = 1;
250
boolean loaded_one = false;
251
String policy_url;
252
253
while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) {
254
try {
255
policy_url = PropertyExpander.expand(policy_url).replace
256
(File.separatorChar, '/');
257
if (debug != null) {
258
debug.println("reading " + policy_url);
259
}
260
init(new URL(policy_url));
261
loaded_one = true;
262
} catch (Exception e) {
263
if (debug != null) {
264
debug.println("Debug info only. Error reading policy " + e);
265
e.printStackTrace();
266
}
267
// ignore that policy
268
}
269
n++;
270
}
271
272
if (loaded_one == false) {
273
// do not load a static policy
274
}
275
}
276
277
/**
278
* Checks public key. If it is marked as trusted in
279
* the identity database, add it to the policy
280
* with the AllPermission.
281
*/
282
private boolean checkForTrustedIdentity(final Certificate cert) {
283
return false;
284
}
285
286
/**
287
* Reads a policy configuration into the Policy object using a
288
* Reader object.
289
*
290
* @param policyFile the policy Reader object.
291
*/
292
private void init(URL policy) {
293
PolicyParser pp = new PolicyParser(expandProperties);
294
try (InputStreamReader isr
295
= new InputStreamReader(PolicyUtil.getInputStream(policy))) {
296
pp.read(isr);
297
KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
298
pp.getKeyStoreType());
299
Enumeration<GrantEntry> enum_ = pp.grantElements();
300
while (enum_.hasMoreElements()) {
301
GrantEntry ge = enum_.nextElement();
302
addGrantEntry(ge, keyStore);
303
}
304
} catch (PolicyParser.ParsingException pe) {
305
System.err.println(AUTH_POLICY +
306
rb.getString(".error.parsing.") + policy);
307
System.err.println(AUTH_POLICY + rb.getString("COLON") +
308
pe.getMessage());
309
if (debug != null) {
310
pe.printStackTrace();
311
}
312
} catch (Exception e) {
313
if (debug != null) {
314
debug.println("error parsing " + policy);
315
debug.println(e.toString());
316
e.printStackTrace();
317
}
318
}
319
}
320
321
/**
322
* Given a PermissionEntry, create a codeSource.
323
*
324
* @return null if signedBy alias is not recognized
325
*/
326
CodeSource getCodeSource(GrantEntry ge, KeyStore keyStore)
327
throws java.net.MalformedURLException
328
{
329
Certificate[] certs = null;
330
if (ge.signedBy != null) {
331
certs = getCertificates(keyStore, ge.signedBy);
332
if (certs == null) {
333
// we don't have a key for this alias,
334
// just return
335
if (debug != null) {
336
debug.println(" no certs for alias " +
337
ge.signedBy + ", ignoring.");
338
}
339
return null;
340
}
341
}
342
343
URL location;
344
if (ge.codeBase != null) {
345
location = new URL(ge.codeBase);
346
} else {
347
location = null;
348
}
349
350
if (ge.principals == null || ge.principals.size() == 0) {
351
return (canonicalizeCodebase
352
(new CodeSource(location, certs),
353
false));
354
} else {
355
return (canonicalizeCodebase
356
(new SubjectCodeSource(null, ge.principals, location, certs),
357
false));
358
}
359
}
360
361
/**
362
* Add one policy entry to the vector.
363
*/
364
private void addGrantEntry(GrantEntry ge, KeyStore keyStore) {
365
366
if (debug != null) {
367
debug.println("Adding policy entry: ");
368
debug.println(" signedBy " + ge.signedBy);
369
debug.println(" codeBase " + ge.codeBase);
370
if (ge.principals != null) {
371
for (PrincipalEntry pppe : ge.principals) {
372
debug.println(" " + pppe.getPrincipalClass() +
373
" " + pppe.getPrincipalName());
374
}
375
}
376
debug.println();
377
}
378
379
try {
380
CodeSource codesource = getCodeSource(ge, keyStore);
381
// skip if signedBy alias was unknown...
382
if (codesource == null) return;
383
384
PolicyEntry entry = new PolicyEntry(codesource);
385
Enumeration<PermissionEntry> enum_ = ge.permissionElements();
386
while (enum_.hasMoreElements()) {
387
PermissionEntry pe = enum_.nextElement();
388
try {
389
// XXX special case PrivateCredentialPermission-SELF
390
Permission perm;
391
if (pe.permission.equals
392
("javax.security.auth.PrivateCredentialPermission") &&
393
pe.name.endsWith(" self")) {
394
perm = getInstance(pe.permission,
395
pe.name + " \"self\"",
396
pe.action);
397
} else {
398
perm = getInstance(pe.permission,
399
pe.name,
400
pe.action);
401
}
402
entry.add(perm);
403
if (debug != null) {
404
debug.println(" "+perm);
405
}
406
} catch (ClassNotFoundException cnfe) {
407
Certificate certs[];
408
if (pe.signedBy != null) {
409
certs = getCertificates(keyStore, pe.signedBy);
410
} else {
411
certs = null;
412
}
413
414
// only add if we had no signer or we had a
415
// a signer and found the keys for it.
416
if (certs != null || pe.signedBy == null) {
417
Permission perm = new UnresolvedPermission(
418
pe.permission,
419
pe.name,
420
pe.action,
421
certs);
422
entry.add(perm);
423
if (debug != null) {
424
debug.println(" "+perm);
425
}
426
}
427
} catch (java.lang.reflect.InvocationTargetException ite) {
428
System.err.println
429
(AUTH_POLICY +
430
rb.getString(".error.adding.Permission.") +
431
pe.permission +
432
rb.getString("SPACE") +
433
ite.getTargetException());
434
} catch (Exception e) {
435
System.err.println
436
(AUTH_POLICY +
437
rb.getString(".error.adding.Permission.") +
438
pe.permission +
439
rb.getString("SPACE") +
440
e);
441
}
442
}
443
policyEntries.addElement(entry);
444
} catch (Exception e) {
445
System.err.println
446
(AUTH_POLICY +
447
rb.getString(".error.adding.Entry.") +
448
ge +
449
rb.getString("SPACE") +
450
e);
451
}
452
453
if (debug != null) {
454
debug.println();
455
}
456
}
457
458
/**
459
* Returns a new Permission object of the given Type. The Permission is
460
* created by getting the
461
* Class object using the <code>Class.forName</code> method, and using
462
* the reflection API to invoke the (String name, String actions)
463
* constructor on the
464
* object.
465
*
466
* @param type the type of Permission being created.
467
* @param name the name of the Permission being created.
468
* @param actions the actions of the Permission being created.
469
*
470
* @exception ClassNotFoundException if the particular Permission
471
* class could not be found.
472
*
473
* @exception IllegalAccessException if the class or initializer is
474
* not accessible.
475
*
476
* @exception InstantiationException if getInstance tries to
477
* instantiate an abstract class or an interface, or if the
478
* instantiation fails for some other reason.
479
*
480
* @exception NoSuchMethodException if the (String, String) constructor
481
* is not found.
482
*
483
* @exception InvocationTargetException if the underlying Permission
484
* constructor throws an exception.
485
*
486
*/
487
private static final Permission getInstance(String type,
488
String name,
489
String actions)
490
throws ClassNotFoundException,
491
InstantiationException,
492
IllegalAccessException,
493
NoSuchMethodException,
494
InvocationTargetException
495
{
496
//XXX we might want to keep a hash of created factories...
497
Class<?> pc = Class.forName(type);
498
Constructor<?> c = pc.getConstructor(PARAMS);
499
return (Permission) c.newInstance(new Object[] { name, actions });
500
}
501
502
/**
503
* Fetch all certs associated with this alias.
504
*/
505
Certificate[] getCertificates(KeyStore keyStore, String aliases) {
506
507
Vector<Certificate> vcerts = null;
508
509
StringTokenizer st = new StringTokenizer(aliases, ",");
510
int n = 0;
511
512
while (st.hasMoreTokens()) {
513
String alias = st.nextToken().trim();
514
n++;
515
Certificate cert = null;
516
// See if this alias's cert has already been cached
517
cert = (Certificate) aliasMapping.get(alias);
518
if (cert == null && keyStore != null) {
519
520
try {
521
cert = keyStore.getCertificate(alias);
522
} catch (KeyStoreException kse) {
523
// never happens, because keystore has already been loaded
524
// when we call this
525
}
526
if (cert != null) {
527
aliasMapping.put(alias, cert);
528
aliasMapping.put(cert, alias);
529
}
530
}
531
532
if (cert != null) {
533
if (vcerts == null) {
534
vcerts = new Vector<Certificate>();
535
}
536
vcerts.addElement(cert);
537
}
538
}
539
540
// make sure n == vcerts.size, since we are doing a logical *and*
541
if (vcerts != null && n == vcerts.size()) {
542
Certificate[] certs = new Certificate[vcerts.size()];
543
vcerts.copyInto(certs);
544
return certs;
545
} else {
546
return null;
547
}
548
}
549
550
/**
551
* Enumerate all the entries in the global policy object.
552
* This method is used by policy admin tools. The tools
553
* should use the Enumeration methods on the returned object
554
* to fetch the elements sequentially.
555
*/
556
private final synchronized Enumeration<PolicyEntry> elements() {
557
return policyEntries.elements();
558
}
559
560
@Override
561
public PermissionCollection getPermissions(final Subject subject,
562
final CodeSource codesource) {
563
564
// 1) if code instantiates PolicyFile directly, then it will need
565
// all the permissions required for the PolicyFile initialization
566
// 2) if code calls Policy.getPolicy, then it simply needs
567
// AuthPermission(getPolicy), and the javax.security.auth.Policy
568
// implementation instantiates PolicyFile in a doPrivileged block
569
// 3) if after instantiating a Policy (either via #1 or #2),
570
// code calls getPermissions, PolicyFile wraps the call
571
// in a doPrivileged block.
572
return AccessController.doPrivileged
573
(new PrivilegedAction<PermissionCollection>() {
574
@Override public PermissionCollection run() {
575
SubjectCodeSource scs = new SubjectCodeSource(
576
subject, null,
577
codesource == null ? null : codesource.getLocation(),
578
codesource == null ? null : codesource.getCertificates());
579
if (initialized) {
580
return getPermissions(new Permissions(), scs);
581
} else {
582
return new PolicyPermissions(AuthPolicyFile.this, scs);
583
}
584
}
585
});
586
}
587
588
/**
589
* Examines the global policy for the specified CodeSource, and
590
* creates a PermissionCollection object with
591
* the set of permissions for that principal's protection domain.
592
*
593
* @param CodeSource the codesource associated with the caller.
594
* This encapsulates the original location of the code (where the code
595
* came from) and the public key(s) of its signer.
596
*
597
* @return the set of permissions according to the policy.
598
*/
599
PermissionCollection getPermissions(CodeSource codesource) {
600
601
if (initialized) {
602
return getPermissions(new Permissions(), codesource);
603
} else {
604
return new PolicyPermissions(this, codesource);
605
}
606
}
607
608
/**
609
* Examines the global policy for the specified CodeSource, and
610
* creates a PermissionCollection object with
611
* the set of permissions for that principal's protection domain.
612
*
613
* @param permissions the permissions to populate
614
* @param codesource the codesource associated with the caller.
615
* This encapsulates the original location of the code (where the code
616
* came from) and the public key(s) of its signer.
617
*
618
* @return the set of permissions according to the policy.
619
*/
620
Permissions getPermissions(final Permissions perms,
621
final CodeSource cs)
622
{
623
if (!initialized) {
624
init();
625
}
626
627
final CodeSource codesource[] = {null};
628
629
codesource[0] = canonicalizeCodebase(cs, true);
630
631
if (debug != null) {
632
debug.println("evaluate(" + codesource[0] + ")\n");
633
}
634
635
// needs to be in a begin/endPrivileged block because
636
// codesource.implies calls URL.equals which does an
637
// InetAddress lookup
638
639
for (int i = 0; i < policyEntries.size(); i++) {
640
641
PolicyEntry entry = policyEntries.elementAt(i);
642
643
if (debug != null) {
644
debug.println("PolicyFile CodeSource implies: " +
645
entry.codesource.toString() + "\n\n" +
646
"\t" + codesource[0].toString() + "\n\n");
647
}
648
649
if (entry.codesource.implies(codesource[0])) {
650
for (int j = 0; j < entry.permissions.size(); j++) {
651
Permission p = entry.permissions.elementAt(j);
652
if (debug != null) {
653
debug.println(" granting " + p);
654
}
655
if (!addSelfPermissions(p, entry.codesource,
656
codesource[0], perms)) {
657
// we could check for duplicates
658
// before adding new permissions,
659
// but the SubjectDomainCombiner
660
// already checks for duplicates later
661
perms.add(p);
662
}
663
}
664
}
665
}
666
667
// now see if any of the keys are trusted ids.
668
669
if (!ignoreIdentityScope) {
670
Certificate certs[] = codesource[0].getCertificates();
671
if (certs != null) {
672
for (int k=0; k < certs.length; k++) {
673
if (aliasMapping.get(certs[k]) == null &&
674
checkForTrustedIdentity(certs[k])) {
675
// checkForTrustedIdentity added it
676
// to the policy for us. next time
677
// around we'll find it. This time
678
// around we need to add it.
679
perms.add(new java.security.AllPermission());
680
}
681
}
682
}
683
}
684
return perms;
685
}
686
687
/**
688
* Returns true if 'Self' permissions were added to the provided
689
* 'perms', and false otherwise.
690
*
691
* <p>
692
*
693
* @param p check to see if this Permission is a "SELF"
694
* PrivateCredentialPermission. <p>
695
*
696
* @param entryCs the codesource for the Policy entry.
697
*
698
* @param accCs the codesource for from the current AccessControlContext.
699
*
700
* @param perms the PermissionCollection where the individual
701
* PrivateCredentialPermissions will be added.
702
*/
703
private boolean addSelfPermissions(final Permission p,
704
CodeSource entryCs,
705
CodeSource accCs,
706
Permissions perms) {
707
708
if (!(p instanceof PrivateCredentialPermission)) {
709
return false;
710
}
711
712
if (!(entryCs instanceof SubjectCodeSource)) {
713
return false;
714
}
715
716
PrivateCredentialPermission pcp = (PrivateCredentialPermission)p;
717
SubjectCodeSource scs = (SubjectCodeSource)entryCs;
718
719
// see if it is a SELF permission
720
String[][] pPrincipals = pcp.getPrincipals();
721
if (pPrincipals.length <= 0 ||
722
!pPrincipals[0][0].equalsIgnoreCase("self") ||
723
!pPrincipals[0][1].equalsIgnoreCase("self")) {
724
725
// regular PrivateCredentialPermission
726
return false;
727
} else {
728
729
// granted a SELF permission - create a
730
// PrivateCredentialPermission for each
731
// of the Policy entry's CodeSource Principals
732
733
if (scs.getPrincipals() == null) {
734
// XXX SubjectCodeSource has no Subject???
735
return true;
736
}
737
738
for (PrincipalEntry principal : scs.getPrincipals()) {
739
740
// if the Policy entry's Principal does not contain a
741
// WILDCARD for the Principal name, then a
742
// new PrivateCredentialPermission is created
743
// for the Principal listed in the Policy entry.
744
// if the Policy entry's Principal contains a WILDCARD
745
// for the Principal name, then a new
746
// PrivateCredentialPermission is created
747
// for each Principal associated with the Subject
748
// in the current ACC.
749
750
String[][] principalInfo = getPrincipalInfo(principal, accCs);
751
752
for (int i = 0; i < principalInfo.length; i++) {
753
754
// here's the new PrivateCredentialPermission
755
756
PrivateCredentialPermission newPcp =
757
new PrivateCredentialPermission
758
(pcp.getCredentialClass() +
759
" " +
760
principalInfo[i][0] +
761
" " +
762
"\"" + principalInfo[i][1] + "\"",
763
"read");
764
765
if (debug != null) {
766
debug.println("adding SELF permission: " +
767
newPcp.toString());
768
}
769
770
perms.add(newPcp);
771
}
772
}
773
}
774
return true;
775
}
776
777
/**
778
* return the principal class/name pair in the 2D array.
779
* array[x][y]: x corresponds to the array length.
780
* if (y == 0), it's the principal class.
781
* if (y == 1), it's the principal name.
782
*/
783
private String[][] getPrincipalInfo(PrincipalEntry principal,
784
final CodeSource accCs) {
785
786
// there are 3 possibilities:
787
// 1) the entry's Principal class and name are not wildcarded
788
// 2) the entry's Principal name is wildcarded only
789
// 3) the entry's Principal class and name are wildcarded
790
791
if (!principal.getPrincipalClass().equals
792
(PrincipalEntry.WILDCARD_CLASS) &&
793
!principal.getPrincipalName().equals
794
(PrincipalEntry.WILDCARD_NAME)) {
795
796
// build a PrivateCredentialPermission for the principal
797
// from the Policy entry
798
String[][] info = new String[1][2];
799
info[0][0] = principal.getPrincipalClass();
800
info[0][1] = principal.getPrincipalName();
801
return info;
802
803
} else if (!principal.getPrincipalClass().equals
804
(PrincipalEntry.WILDCARD_CLASS) &&
805
principal.getPrincipalName().equals
806
(PrincipalEntry.WILDCARD_NAME)) {
807
808
// build a PrivateCredentialPermission for all
809
// the Subject's principals that are instances of principalClass
810
811
// the accCs is guaranteed to be a SubjectCodeSource
812
// because the earlier CodeSource.implies succeeded
813
SubjectCodeSource scs = (SubjectCodeSource)accCs;
814
815
Set<? extends Principal> principalSet = null;
816
try {
817
// principal.principalClass should extend Principal
818
// If it doesn't, we should stop here with a ClassCastException.
819
@SuppressWarnings("unchecked")
820
Class<? extends Principal> pClass = (Class<? extends Principal>)
821
Class.forName(principal.getPrincipalClass(), false,
822
ClassLoader.getSystemClassLoader());
823
principalSet = scs.getSubject().getPrincipals(pClass);
824
} catch (Exception e) {
825
if (debug != null) {
826
debug.println("problem finding Principal Class " +
827
"when expanding SELF permission: " +
828
e.toString());
829
}
830
}
831
832
if (principalSet == null) {
833
// error
834
return new String[0][0];
835
}
836
837
String[][] info = new String[principalSet.size()][2];
838
839
int i = 0;
840
for (Principal p : principalSet) {
841
info[i][0] = p.getClass().getName();
842
info[i][1] = p.getName();
843
i++;
844
}
845
return info;
846
847
} else {
848
849
// build a PrivateCredentialPermission for every
850
// one of the current Subject's principals
851
852
// the accCs is guaranteed to be a SubjectCodeSource
853
// because the earlier CodeSource.implies succeeded
854
SubjectCodeSource scs = (SubjectCodeSource)accCs;
855
Set<Principal> principalSet = scs.getSubject().getPrincipals();
856
857
String[][] info = new String[principalSet.size()][2];
858
859
int i = 0;
860
for (Principal p : principalSet) {
861
info[i][0] = p.getClass().getName();
862
info[i][1] = p.getName();
863
i++;
864
}
865
return info;
866
}
867
}
868
869
/*
870
* Returns the signer certificates from the list of certificates associated
871
* with the given code source.
872
*
873
* The signer certificates are those certificates that were used to verify
874
* signed code originating from the codesource location.
875
*
876
* This method assumes that in the given code source, each signer
877
* certificate is followed by its supporting certificate chain
878
* (which may be empty), and that the signer certificate and its
879
* supporting certificate chain are ordered bottom-to-top (i.e., with the
880
* signer certificate first and the (root) certificate authority last).
881
*/
882
Certificate[] getSignerCertificates(CodeSource cs) {
883
Certificate[] certs = null;
884
if ((certs = cs.getCertificates()) == null) {
885
return null;
886
}
887
for (int i = 0; i < certs.length; i++) {
888
if (!(certs[i] instanceof X509Certificate))
889
return cs.getCertificates();
890
}
891
892
// Do we have to do anything?
893
int i = 0;
894
int count = 0;
895
while (i < certs.length) {
896
count++;
897
while (((i+1) < certs.length)
898
&& ((X509Certificate)certs[i]).getIssuerDN().equals(
899
((X509Certificate)certs[i+1]).getSubjectDN())) {
900
i++;
901
}
902
i++;
903
}
904
if (count == certs.length) {
905
// Done
906
return certs;
907
}
908
909
ArrayList<Certificate> userCertList = new ArrayList<>();
910
i = 0;
911
while (i < certs.length) {
912
userCertList.add(certs[i]);
913
while (((i+1) < certs.length)
914
&& ((X509Certificate)certs[i]).getIssuerDN().equals(
915
((X509Certificate)certs[i+1]).getSubjectDN())) {
916
i++;
917
}
918
i++;
919
}
920
Certificate[] userCerts = new Certificate[userCertList.size()];
921
userCertList.toArray(userCerts);
922
return userCerts;
923
}
924
925
private CodeSource canonicalizeCodebase(CodeSource cs,
926
boolean extractSignerCerts) {
927
CodeSource canonCs = cs;
928
if (cs.getLocation() != null &&
929
cs.getLocation().getProtocol().equalsIgnoreCase("file")) {
930
try {
931
String path = cs.getLocation().getFile().replace
932
('/',
933
File.separatorChar);
934
URL csUrl = null;
935
if (path.endsWith("*")) {
936
// remove trailing '*' because it causes canonicalization
937
// to fail on win32
938
path = path.substring(0, path.length()-1);
939
boolean appendFileSep = false;
940
if (path.endsWith(File.separator)) {
941
appendFileSep = true;
942
}
943
if (path.equals("")) {
944
path = System.getProperty("user.dir");
945
}
946
File f = new File(path);
947
path = f.getCanonicalPath();
948
StringBuffer sb = new StringBuffer(path);
949
// reappend '*' to canonicalized filename (note that
950
// canonicalization may have removed trailing file
951
// separator, so we have to check for that, too)
952
if (!path.endsWith(File.separator) &&
953
(appendFileSep || f.isDirectory())) {
954
sb.append(File.separatorChar);
955
}
956
sb.append('*');
957
path = sb.toString();
958
} else {
959
path = new File(path).getCanonicalPath();
960
}
961
csUrl = new File(path).toURL();
962
963
if (cs instanceof SubjectCodeSource) {
964
SubjectCodeSource scs = (SubjectCodeSource)cs;
965
if (extractSignerCerts) {
966
canonCs = new SubjectCodeSource(scs.getSubject(),
967
scs.getPrincipals(),
968
csUrl,
969
getSignerCertificates(scs));
970
} else {
971
canonCs = new SubjectCodeSource(scs.getSubject(),
972
scs.getPrincipals(),
973
csUrl,
974
scs.getCertificates());
975
}
976
} else {
977
if (extractSignerCerts) {
978
canonCs = new CodeSource(csUrl,
979
getSignerCertificates(cs));
980
} else {
981
canonCs = new CodeSource(csUrl,
982
cs.getCertificates());
983
}
984
}
985
} catch (IOException ioe) {
986
// leave codesource as it is, unless we have to extract its
987
// signer certificates
988
if (extractSignerCerts) {
989
if (!(cs instanceof SubjectCodeSource)) {
990
canonCs = new CodeSource(cs.getLocation(),
991
getSignerCertificates(cs));
992
} else {
993
SubjectCodeSource scs = (SubjectCodeSource)cs;
994
canonCs = new SubjectCodeSource(scs.getSubject(),
995
scs.getPrincipals(),
996
scs.getLocation(),
997
getSignerCertificates(scs));
998
}
999
}
1000
}
1001
} else {
1002
if (extractSignerCerts) {
1003
if (!(cs instanceof SubjectCodeSource)) {
1004
canonCs = new CodeSource(cs.getLocation(),
1005
getSignerCertificates(cs));
1006
} else {
1007
SubjectCodeSource scs = (SubjectCodeSource)cs;
1008
canonCs = new SubjectCodeSource(scs.getSubject(),
1009
scs.getPrincipals(),
1010
scs.getLocation(),
1011
getSignerCertificates(scs));
1012
}
1013
}
1014
}
1015
return canonCs;
1016
}
1017
1018
/**
1019
* Each entry in the policy configuration file is represented by a
1020
* PolicyEntry object. <p>
1021
*
1022
* A PolicyEntry is a (CodeSource,Permission) pair. The
1023
* CodeSource contains the (URL, PublicKey) that together identify
1024
* where the Java bytecodes come from and who (if anyone) signed
1025
* them. The URL could refer to localhost. The URL could also be
1026
* null, meaning that this policy entry is given to all comers, as
1027
* long as they match the signer field. The signer could be null,
1028
* meaning the code is not signed. <p>
1029
*
1030
* The Permission contains the (Type, Name, Action) triplet. <p>
1031
*
1032
* For now, the Policy object retrieves the public key from the
1033
* X.509 certificate on disk that corresponds to the signedBy
1034
* alias specified in the Policy config file. For reasons of
1035
* efficiency, the Policy object keeps a hashtable of certs already
1036
* read in. This could be replaced by a secure internal key
1037
* store.
1038
*
1039
* <p>
1040
* For example, the entry
1041
* <pre>
1042
* permission java.io.File "/tmp", "read,write",
1043
* signedBy "Duke";
1044
* </pre>
1045
* is represented internally
1046
* <pre>
1047
*
1048
* FilePermission f = new FilePermission("/tmp", "read,write");
1049
* PublicKey p = publickeys.get("Duke");
1050
* URL u = InetAddress.getLocalHost();
1051
* CodeBase c = new CodeBase( p, u );
1052
* pe = new PolicyEntry(f, c);
1053
* </pre>
1054
*
1055
* @author Marianne Mueller
1056
* @author Roland Schemers
1057
* @see java.security.CodeSource
1058
* @see java.security.Policy
1059
* @see java.security.Permissions
1060
* @see java.security.ProtectionDomain
1061
*/
1062
private static class PolicyEntry {
1063
1064
CodeSource codesource;
1065
Vector<Permission> permissions;
1066
1067
/**
1068
* Given a Permission and a CodeSource, create a policy entry.
1069
*
1070
* XXX Decide if/how to add validity fields and "purpose" fields to
1071
* XXX policy entries
1072
*
1073
* @param cs the CodeSource, which encapsulates the URL and the public
1074
* key attributes from the policy config file. Validity checks
1075
* are performed on the public key before PolicyEntry is called.
1076
*
1077
*/
1078
PolicyEntry(CodeSource cs) {
1079
this.codesource = cs;
1080
this.permissions = new Vector<Permission>();
1081
}
1082
1083
/**
1084
* add a Permission object to this entry.
1085
*/
1086
void add(Permission p) {
1087
permissions.addElement(p);
1088
}
1089
1090
/**
1091
* Return the CodeSource for this policy entry
1092
*/
1093
CodeSource getCodeSource() {
1094
return this.codesource;
1095
}
1096
1097
@Override
1098
public String toString(){
1099
StringBuffer sb = new StringBuffer();
1100
sb.append(rb.getString("LPARAM"));
1101
sb.append(getCodeSource());
1102
sb.append("\n");
1103
for (int j = 0; j < permissions.size(); j++) {
1104
Permission p = permissions.elementAt(j);
1105
sb.append(rb.getString("SPACE"));
1106
sb.append(rb.getString("SPACE"));
1107
sb.append(p);
1108
sb.append(rb.getString("NEWLINE"));
1109
}
1110
sb.append(rb.getString("RPARAM"));
1111
sb.append(rb.getString("NEWLINE"));
1112
return sb.toString();
1113
}
1114
1115
}
1116
}
1117
1118
@SuppressWarnings("deprecation")
1119
class PolicyPermissions extends PermissionCollection {
1120
1121
private static final long serialVersionUID = -1954188373270545523L;
1122
1123
private CodeSource codesource;
1124
private Permissions perms;
1125
private AuthPolicyFile policy;
1126
private boolean notInit; // have we pulled in the policy permissions yet?
1127
private Vector<Permission> additionalPerms;
1128
1129
PolicyPermissions(AuthPolicyFile policy,
1130
CodeSource codesource)
1131
{
1132
this.codesource = codesource;
1133
this.policy = policy;
1134
this.perms = null;
1135
this.notInit = true;
1136
this.additionalPerms = null;
1137
}
1138
1139
@Override
1140
public void add(Permission permission) {
1141
if (isReadOnly())
1142
throw new SecurityException
1143
(AuthPolicyFile.rb.getString
1144
("attempt.to.add.a.Permission.to.a.readonly.PermissionCollection"));
1145
1146
if (perms == null) {
1147
if (additionalPerms == null) {
1148
additionalPerms = new Vector<Permission>();
1149
}
1150
additionalPerms.add(permission);
1151
} else {
1152
perms.add(permission);
1153
}
1154
}
1155
1156
private synchronized void init() {
1157
if (notInit) {
1158
if (perms == null) {
1159
perms = new Permissions();
1160
}
1161
if (additionalPerms != null) {
1162
Enumeration<Permission> e = additionalPerms.elements();
1163
while (e.hasMoreElements()) {
1164
perms.add(e.nextElement());
1165
}
1166
additionalPerms = null;
1167
}
1168
policy.getPermissions(perms, codesource);
1169
notInit = false;
1170
}
1171
}
1172
1173
@Override
1174
public boolean implies(Permission permission) {
1175
if (notInit) {
1176
init();
1177
}
1178
return perms.implies(permission);
1179
}
1180
1181
@Override
1182
public Enumeration<Permission> elements() {
1183
if (notInit) {
1184
init();
1185
}
1186
return perms.elements();
1187
}
1188
1189
@Override
1190
public String toString() {
1191
if (notInit) {
1192
init();
1193
}
1194
return perms.toString();
1195
}
1196
}
1197
1198