Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java
38924 views
/*1* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.media.sound;2627import java.io.BufferedInputStream;28import java.io.InputStream;29import java.io.File;30import java.io.FileInputStream;3132import java.util.ArrayList;33import java.util.Iterator;34import java.util.List;35import java.util.Properties;36import java.util.ServiceLoader;3738import java.security.AccessController;39import java.security.PrivilegedAction;4041import javax.sound.sampled.AudioPermission;4243/** Managing security in the Java Sound implementation.44* This class contains all code that uses and is used by45* SecurityManager.doPrivileged().46*47* @author Matthias Pfisterer48*/49final class JSSecurityManager {5051/** Prevent instantiation.52*/53private JSSecurityManager() {54}5556/** Checks if the VM currently has a SecurityManager installed.57* Note that this may change over time. So the result of this method58* should not be cached.59*60* @return true if a SecurityManger is installed, false otherwise.61*/62private static boolean hasSecurityManager() {63return (System.getSecurityManager() != null);64}656667static void checkRecordPermission() throws SecurityException {68if(Printer.trace) Printer.trace("JSSecurityManager.checkRecordPermission()");69SecurityManager sm = System.getSecurityManager();70if (sm != null) {71sm.checkPermission(new AudioPermission("record"));72}73}7475/** Load properties from a file.76This method tries to load properties from the filename give into77the passed properties object.78If the file cannot be found or something else goes wrong,79the method silently fails.80@param properties The properties bundle to store the values of the81properties file.82@param filename The filename of the properties file to load. This83filename is interpreted as relative to the subdirectory "lib" in84the JRE directory.85*/86static void loadProperties(final Properties properties,87final String filename) {88if(hasSecurityManager()) {89try {90// invoke the privileged action using 1.2 security91PrivilegedAction<Void> action = new PrivilegedAction<Void>() {92public Void run() {93loadPropertiesImpl(properties, filename);94return null;95}96};97AccessController.doPrivileged(action);98if(Printer.debug)Printer.debug("Loaded properties with JDK 1.2 security");99} catch (Exception e) {100if(Printer.debug)Printer.debug("Exception loading properties with JDK 1.2 security");101// try without using JDK 1.2 security102loadPropertiesImpl(properties, filename);103}104} else {105// not JDK 1.2 security, assume we already have permission106loadPropertiesImpl(properties, filename);107}108}109110111private static void loadPropertiesImpl(Properties properties,112String filename) {113if(Printer.trace)Printer.trace(">> JSSecurityManager: loadPropertiesImpl()");114String fname = System.getProperty("java.home");115try {116if (fname == null) {117throw new Error("Can't find java.home ??");118}119File f = new File(fname, "lib");120f = new File(f, filename);121fname = f.getCanonicalPath();122InputStream in = new FileInputStream(fname);123BufferedInputStream bin = new BufferedInputStream(in);124try {125properties.load(bin);126} finally {127if (in != null) {128in.close();129}130}131} catch (Throwable t) {132if (Printer.trace) {133System.err.println("Could not load properties file \"" + fname + "\"");134t.printStackTrace();135}136}137if(Printer.trace)Printer.trace("<< JSSecurityManager: loadPropertiesImpl() completed");138}139140/** Create a Thread in the current ThreadGroup.141*/142static Thread createThread(final Runnable runnable,143final String threadName,144final boolean isDaemon, final int priority,145final boolean doStart) {146Thread thread = new Thread(runnable);147if (threadName != null) {148thread.setName(threadName);149}150thread.setDaemon(isDaemon);151if (priority >= 0) {152thread.setPriority(priority);153}154if (doStart) {155thread.start();156}157return thread;158}159160static synchronized <T> List<T> getProviders(final Class<T> providerClass) {161List<T> p = new ArrayList<>(7);162// ServiceLoader creates "lazy" iterator instance, but it ensures that163// next/hasNext run with permissions that are restricted by whatever164// creates the ServiceLoader instance, so it requires to be called from165// privileged section166final PrivilegedAction<Iterator<T>> psAction =167new PrivilegedAction<Iterator<T>>() {168@Override169public Iterator<T> run() {170return ServiceLoader.load(providerClass).iterator();171}172};173final Iterator<T> ps = AccessController.doPrivileged(psAction);174175// the iterator's hasNext() method looks through classpath for176// the provider class names, so it requires read permissions177PrivilegedAction<Boolean> hasNextAction = new PrivilegedAction<Boolean>() {178public Boolean run() {179return ps.hasNext();180}181};182183while (AccessController.doPrivileged(hasNextAction)) {184try {185// the iterator's next() method creates instances of the186// providers and it should be called in the current security187// context188T provider = ps.next();189if (providerClass.isInstance(provider)) {190// $$mp 2003-08-22191// Always adding at the beginning reverses the192// order of the providers. So we no longer have193// to do this in AudioSystem and MidiSystem.194p.add(0, provider);195}196} catch (Throwable t) {197//$$fb 2002-11-07: do not fail on SPI not found198if (Printer.err) t.printStackTrace();199}200}201return p;202}203}204205206