< prev index next >

src/java.base/share/classes/javax/security/auth/SubjectDomainCombiner.java

Print this page
rev 48948 : 8191139: Remove deprecated javax.security.auth.Policy API
   1 /*
   2  * Copyright (c) 1999, 2016, 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 javax.security.auth;
  27 
  28 import java.security.AccessController;
  29 import java.security.Permission;
  30 import java.security.Permissions;
  31 import java.security.PermissionCollection;
  32 import java.security.Principal;
  33 import java.security.PrivilegedAction;
  34 import java.security.ProtectionDomain;
  35 import java.security.Security;
  36 import java.util.Set;
  37 import java.util.WeakHashMap;
  38 import java.lang.ref.WeakReference;
  39 
  40 /**
  41  * A {@code SubjectDomainCombiner} updates ProtectionDomains
  42  * with Principals from the {@code Subject} associated with this
  43  * {@code SubjectDomainCombiner}.
  44  *
  45  * @since 1.4
  46  */
  47 public class SubjectDomainCombiner implements java.security.DomainCombiner {
  48 
  49     private Subject subject;
  50     private WeakKeyValueMap<ProtectionDomain, ProtectionDomain> cachedPDs =
  51                 new WeakKeyValueMap<>();
  52     private Set<Principal> principalSet;
  53     private Principal[] principals;
  54 
  55     private static final sun.security.util.Debug debug =
  56         sun.security.util.Debug.getInstance("combiner",
  57                                         "\t[SubjectDomainCombiner]");
  58 
  59     @SuppressWarnings({"deprecation", "removal"})
  60     // Note: check only at classloading time, not dynamically during combine()
  61     private static final boolean useJavaxPolicy =
  62         javax.security.auth.Policy.isCustomPolicySet(debug);
  63 
  64     // Relevant only when useJavaxPolicy is true
  65     private static final boolean allowCaching =
  66                                         (useJavaxPolicy && cachePolicy());
  67 
  68     /**
  69      * Associate the provided {@code Subject} with this
  70      * {@code SubjectDomainCombiner}.
  71      *
  72      * @param subject the {@code Subject} to be associated with
  73      *          with this {@code SubjectDomainCombiner}.
  74      */
  75     public SubjectDomainCombiner(Subject subject) {
  76         this.subject = subject;
  77 
  78         if (subject.isReadOnly()) {
  79             principalSet = subject.getPrincipals();
  80             principals = principalSet.toArray
  81                         (new Principal[principalSet.size()]);
  82         }
  83     }
  84 
  85     /**
  86      * Get the {@code Subject} associated with this
  87      * {@code SubjectDomainCombiner}.


 179             // array instance in this case
 180 
 181             return assignedDomains;
 182         }
 183 
 184         // optimize currentDomains
 185         //
 186         // No need to optimize assignedDomains because it should
 187         // have been previously optimized (when it was set).
 188 
 189         currentDomains = optimize(currentDomains);
 190         if (debug != null) {
 191             debug.println("after optimize");
 192             printInputDomains(currentDomains, assignedDomains);
 193         }
 194 
 195         if (currentDomains == null && assignedDomains == null) {
 196             return null;
 197         }
 198 
 199         // maintain backwards compatibility for developers who provide
 200         // their own custom javax.security.auth.Policy implementations
 201         if (useJavaxPolicy) {
 202             return combineJavaxPolicy(currentDomains, assignedDomains);
 203         }
 204 
 205         int cLen = (currentDomains == null ? 0 : currentDomains.length);
 206         int aLen = (assignedDomains == null ? 0 : assignedDomains.length);
 207 
 208         // the ProtectionDomains for the new AccessControlContext
 209         // that we will return
 210         ProtectionDomain[] newDomains = new ProtectionDomain[cLen + aLen];
 211 
 212         boolean allNew = true;
 213         synchronized(cachedPDs) {
 214             if (!subject.isReadOnly() &&
 215                 !subject.getPrincipals().equals(principalSet)) {
 216 
 217                 // if the Subject was mutated, clear the PD cache
 218                 Set<Principal> newSet = subject.getPrincipals();
 219                 synchronized(newSet) {
 220                     principalSet = new java.util.HashSet<Principal>(newSet);
 221                 }
 222                 principals = principalSet.toArray
 223                         (new Principal[principalSet.size()]);
 224                 cachedPDs.clear();


 275         if (debug != null) {
 276             if (newDomains == null || newDomains.length == 0) {
 277                 debug.println("returning null");
 278             } else {
 279                 debug.println("combinedDomains: ");
 280                 for (int i = 0; i < newDomains.length; i++) {
 281                     debug.println("newDomain " + i + ": " +
 282                                   printDomain(newDomains[i]));
 283                 }
 284             }
 285         }
 286 
 287         // return the new ProtectionDomains
 288         if (newDomains == null || newDomains.length == 0) {
 289             return null;
 290         } else {
 291             return newDomains;
 292         }
 293     }
 294 
 295     /**
 296      * Use the javax.security.auth.Policy implementation
 297      */
 298     private ProtectionDomain[] combineJavaxPolicy(
 299         ProtectionDomain[] currentDomains,
 300         ProtectionDomain[] assignedDomains) {
 301 
 302         if (!allowCaching) {
 303             java.security.AccessController.doPrivileged
 304                 (new PrivilegedAction<Void>() {
 305                     @SuppressWarnings({"deprecation", "removal"})
 306                     public Void run() {
 307                         // Call refresh only caching is disallowed
 308                         javax.security.auth.Policy.getPolicy().refresh();
 309                         return null;
 310                     }
 311                 });
 312         }
 313 
 314 
 315         int cLen = (currentDomains == null ? 0 : currentDomains.length);
 316         int aLen = (assignedDomains == null ? 0 : assignedDomains.length);
 317 
 318         // the ProtectionDomains for the new AccessControlContext
 319         // that we will return
 320         ProtectionDomain[] newDomains = new ProtectionDomain[cLen + aLen];
 321 
 322         synchronized(cachedPDs) {
 323             if (!subject.isReadOnly() &&
 324                 !subject.getPrincipals().equals(principalSet)) {
 325 
 326                 // if the Subject was mutated, clear the PD cache
 327                 Set<Principal> newSet = subject.getPrincipals();
 328                 synchronized(newSet) {
 329                     principalSet = new java.util.HashSet<Principal>(newSet);
 330                 }
 331                 principals = principalSet.toArray
 332                         (new Principal[principalSet.size()]);
 333                 cachedPDs.clear();
 334 
 335                 if (debug != null) {
 336                     debug.println("Subject mutated - clearing cache");
 337                 }
 338             }
 339 
 340             for (int i = 0; i < cLen; i++) {
 341                 ProtectionDomain pd = currentDomains[i];
 342                 ProtectionDomain subjectPd = cachedPDs.getValue(pd);
 343 
 344                 if (subjectPd == null) {
 345                     if (pd.staticPermissionsOnly()) {
 346                         // keep static ProtectionDomain objects static
 347                         subjectPd = pd;
 348                     } else {
 349                         // XXX
 350                         // we must first add the original permissions.
 351                         // that way when we later add the new JAAS permissions,
 352                         // any unresolved JAAS-related permissions will
 353                         // automatically get resolved.
 354 
 355                         // get the original perms
 356                         Permissions perms = new Permissions();
 357                         PermissionCollection coll = pd.getPermissions();
 358                         java.util.Enumeration<Permission> e;
 359                         if (coll != null) {
 360                             synchronized (coll) {
 361                                 e = coll.elements();
 362                                 while (e.hasMoreElements()) {
 363                                     Permission newPerm =
 364                                         e.nextElement();
 365                                     perms.add(newPerm);
 366                                 }
 367                             }
 368                         }
 369 
 370                         // get perms from the policy
 371                         final java.security.CodeSource finalCs = pd.getCodeSource();
 372                         final Subject finalS = subject;
 373                         PermissionCollection newPerms =
 374                             java.security.AccessController.doPrivileged
 375                             (new PrivilegedAction<PermissionCollection>() {
 376                             @SuppressWarnings({"deprecation", "removal"})
 377                             public PermissionCollection run() {
 378                                 return
 379                                     javax.security.auth.Policy.getPolicy().getPermissions
 380                                     (finalS, finalCs);
 381                             }
 382                         });
 383 
 384                         // add the newly granted perms,
 385                         // avoiding duplicates
 386                         synchronized (newPerms) {
 387                             e = newPerms.elements();
 388                             while (e.hasMoreElements()) {
 389                                 Permission newPerm = e.nextElement();
 390                                 if (!perms.implies(newPerm)) {
 391                                     perms.add(newPerm);
 392                                     if (debug != null)
 393                                         debug.println (
 394                                             "Adding perm " + newPerm + "\n");
 395                                 }
 396                             }
 397                         }
 398                         subjectPd = new ProtectionDomain
 399                             (finalCs, perms, pd.getClassLoader(), principals);
 400                     }
 401                     if (allowCaching)
 402                         cachedPDs.putValue(pd, subjectPd);
 403                 }
 404                 newDomains[i] = subjectPd;
 405             }
 406         }
 407 
 408         if (debug != null) {
 409             debug.println("updated current: ");
 410             for (int i = 0; i < cLen; i++) {
 411                 debug.println("\tupdated[" + i + "] = " + newDomains[i]);
 412             }
 413         }
 414 
 415         // now add on the assigned domains
 416         if (aLen > 0) {
 417             System.arraycopy(assignedDomains, 0, newDomains, cLen, aLen);
 418         }
 419 
 420         if (debug != null) {
 421             if (newDomains == null || newDomains.length == 0) {
 422                 debug.println("returning null");
 423             } else {
 424                 debug.println("combinedDomains: ");
 425                 for (int i = 0; i < newDomains.length; i++) {
 426                     debug.println("newDomain " + i + ": " +
 427                         newDomains[i].toString());
 428                 }
 429             }
 430         }
 431 
 432         // return the new ProtectionDomains
 433         if (newDomains == null || newDomains.length == 0) {
 434             return null;
 435         } else {
 436             return newDomains;
 437         }
 438     }
 439 
 440     private static ProtectionDomain[] optimize(ProtectionDomain[] domains) {
 441         if (domains == null || domains.length == 0)
 442             return null;
 443 
 444         ProtectionDomain[] optimized = new ProtectionDomain[domains.length];
 445         ProtectionDomain pd;
 446         int num = 0;
 447         for (int i = 0; i < domains.length; i++) {
 448 
 449             // skip domains with AllPermission
 450             // XXX
 451             //
 452             //  if (domains[i].implies(ALL_PERMISSION))
 453             //  continue;
 454 
 455             // skip System Domains
 456             if ((pd = domains[i]) != null) {
 457 
 458                 // remove duplicates
 459                 boolean found = false;
 460                 for (int j = 0; j < num && !found; j++) {
 461                     found = (optimized[j] == pd);
 462                 }
 463                 if (!found) {
 464                     optimized[num++] = pd;
 465                 }
 466             }
 467         }
 468 
 469         // resize the array if necessary
 470         if (num > 0 && num < domains.length) {
 471             ProtectionDomain[] downSize = new ProtectionDomain[num];
 472             System.arraycopy(optimized, 0, downSize, 0, downSize.length);
 473             optimized = downSize;
 474         }
 475 
 476         return ((num == 0 || optimized.length == 0) ? null : optimized);
 477     }
 478 
 479     private static boolean cachePolicy() {
 480         String s = AccessController.doPrivileged
 481             (new PrivilegedAction<String>() {
 482             public String run() {
 483                 return Security.getProperty("cache.auth.policy");
 484             }
 485         });
 486         if (s != null) {
 487             return Boolean.parseBoolean(s);
 488         }
 489 
 490         // cache by default
 491         return true;
 492     }
 493 
 494     private static void printInputDomains(ProtectionDomain[] currentDomains,
 495                                 ProtectionDomain[] assignedDomains) {
 496         if (currentDomains == null || currentDomains.length == 0) {
 497             debug.println("currentDomains null or 0 length");
 498         } else {
 499             for (int i = 0; currentDomains != null &&
 500                         i < currentDomains.length; i++) {
 501                 if (currentDomains[i] == null) {
 502                     debug.println("currentDomain " + i + ": SystemDomain");
 503                 } else {
 504                     debug.println("currentDomain " + i + ": " +
 505                                 printDomain(currentDomains[i]));
 506                 }
 507             }
 508         }
 509 
 510         if (assignedDomains == null || assignedDomains.length == 0) {
 511             debug.println("assignedDomains null or 0 length");
 512         } else {
 513             debug.println("assignedDomains = ");


   1 /*
   2  * Copyright (c) 1999, 2018, 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 javax.security.auth;
  27 
  28 import java.security.AccessController;



  29 import java.security.Principal;
  30 import java.security.PrivilegedAction;
  31 import java.security.ProtectionDomain;

  32 import java.util.Set;
  33 import java.util.WeakHashMap;
  34 import java.lang.ref.WeakReference;
  35 
  36 /**
  37  * A {@code SubjectDomainCombiner} updates ProtectionDomains
  38  * with Principals from the {@code Subject} associated with this
  39  * {@code SubjectDomainCombiner}.
  40  *
  41  * @since 1.4
  42  */
  43 public class SubjectDomainCombiner implements java.security.DomainCombiner {
  44 
  45     private Subject subject;
  46     private WeakKeyValueMap<ProtectionDomain, ProtectionDomain> cachedPDs =
  47                 new WeakKeyValueMap<>();
  48     private Set<Principal> principalSet;
  49     private Principal[] principals;
  50 
  51     private static final sun.security.util.Debug debug =
  52         sun.security.util.Debug.getInstance("combiner",
  53                                         "\t[SubjectDomainCombiner]");
  54 









  55     /**
  56      * Associate the provided {@code Subject} with this
  57      * {@code SubjectDomainCombiner}.
  58      *
  59      * @param subject the {@code Subject} to be associated with
  60      *          with this {@code SubjectDomainCombiner}.
  61      */
  62     public SubjectDomainCombiner(Subject subject) {
  63         this.subject = subject;
  64 
  65         if (subject.isReadOnly()) {
  66             principalSet = subject.getPrincipals();
  67             principals = principalSet.toArray
  68                         (new Principal[principalSet.size()]);
  69         }
  70     }
  71 
  72     /**
  73      * Get the {@code Subject} associated with this
  74      * {@code SubjectDomainCombiner}.


 166             // array instance in this case
 167 
 168             return assignedDomains;
 169         }
 170 
 171         // optimize currentDomains
 172         //
 173         // No need to optimize assignedDomains because it should
 174         // have been previously optimized (when it was set).
 175 
 176         currentDomains = optimize(currentDomains);
 177         if (debug != null) {
 178             debug.println("after optimize");
 179             printInputDomains(currentDomains, assignedDomains);
 180         }
 181 
 182         if (currentDomains == null && assignedDomains == null) {
 183             return null;
 184         }
 185 






 186         int cLen = (currentDomains == null ? 0 : currentDomains.length);
 187         int aLen = (assignedDomains == null ? 0 : assignedDomains.length);
 188 
 189         // the ProtectionDomains for the new AccessControlContext
 190         // that we will return
 191         ProtectionDomain[] newDomains = new ProtectionDomain[cLen + aLen];
 192 
 193         boolean allNew = true;
 194         synchronized(cachedPDs) {
 195             if (!subject.isReadOnly() &&
 196                 !subject.getPrincipals().equals(principalSet)) {
 197 
 198                 // if the Subject was mutated, clear the PD cache
 199                 Set<Principal> newSet = subject.getPrincipals();
 200                 synchronized(newSet) {
 201                     principalSet = new java.util.HashSet<Principal>(newSet);
 202                 }
 203                 principals = principalSet.toArray
 204                         (new Principal[principalSet.size()]);
 205                 cachedPDs.clear();


 256         if (debug != null) {
 257             if (newDomains == null || newDomains.length == 0) {
 258                 debug.println("returning null");
 259             } else {
 260                 debug.println("combinedDomains: ");
 261                 for (int i = 0; i < newDomains.length; i++) {
 262                     debug.println("newDomain " + i + ": " +
 263                                   printDomain(newDomains[i]));
 264                 }
 265             }
 266         }
 267 
 268         // return the new ProtectionDomains
 269         if (newDomains == null || newDomains.length == 0) {
 270             return null;
 271         } else {
 272             return newDomains;
 273         }
 274     }
 275 

















































































































































 276     private static ProtectionDomain[] optimize(ProtectionDomain[] domains) {
 277         if (domains == null || domains.length == 0)
 278             return null;
 279 
 280         ProtectionDomain[] optimized = new ProtectionDomain[domains.length];
 281         ProtectionDomain pd;
 282         int num = 0;
 283         for (int i = 0; i < domains.length; i++) {
 284 
 285             // skip domains with AllPermission
 286             // XXX
 287             //
 288             //  if (domains[i].implies(ALL_PERMISSION))
 289             //  continue;
 290 
 291             // skip System Domains
 292             if ((pd = domains[i]) != null) {
 293 
 294                 // remove duplicates
 295                 boolean found = false;
 296                 for (int j = 0; j < num && !found; j++) {
 297                     found = (optimized[j] == pd);
 298                 }
 299                 if (!found) {
 300                     optimized[num++] = pd;
 301                 }
 302             }
 303         }
 304 
 305         // resize the array if necessary
 306         if (num > 0 && num < domains.length) {
 307             ProtectionDomain[] downSize = new ProtectionDomain[num];
 308             System.arraycopy(optimized, 0, downSize, 0, downSize.length);
 309             optimized = downSize;
 310         }
 311 
 312         return ((num == 0 || optimized.length == 0) ? null : optimized);
 313     }
 314 















 315     private static void printInputDomains(ProtectionDomain[] currentDomains,
 316                                 ProtectionDomain[] assignedDomains) {
 317         if (currentDomains == null || currentDomains.length == 0) {
 318             debug.println("currentDomains null or 0 length");
 319         } else {
 320             for (int i = 0; currentDomains != null &&
 321                         i < currentDomains.length; i++) {
 322                 if (currentDomains[i] == null) {
 323                     debug.println("currentDomain " + i + ": SystemDomain");
 324                 } else {
 325                     debug.println("currentDomain " + i + ": " +
 326                                 printDomain(currentDomains[i]));
 327                 }
 328             }
 329         }
 330 
 331         if (assignedDomains == null || assignedDomains.length == 0) {
 332             debug.println("assignedDomains null or 0 length");
 333         } else {
 334             debug.println("assignedDomains = ");


< prev index next >