jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java
changeset 2 90ce3da70b43
child 3453 55b3a9c935cd
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1999-2007 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package com.sun.media.sound;
       
    27 
       
    28 import java.io.BufferedInputStream;
       
    29 import java.io.InputStream;
       
    30 import java.io.File;
       
    31 import java.io.FileInputStream;
       
    32 
       
    33 import java.util.ArrayList;
       
    34 import java.util.Iterator;
       
    35 import java.util.List;
       
    36 import java.util.Properties;
       
    37 
       
    38 import java.security.AccessController;
       
    39 import java.security.PrivilegedAction;
       
    40 
       
    41 import javax.sound.sampled.AudioPermission;
       
    42 
       
    43 import sun.misc.Service;
       
    44 
       
    45 
       
    46 /** Managing security in the Java Sound implementation.
       
    47  * This class contains all code that uses and is used by
       
    48  * SecurityManager.doPrivileged().
       
    49  *
       
    50  * @author Matthias Pfisterer
       
    51  */
       
    52 class JSSecurityManager {
       
    53 
       
    54     /** Prevent instantiation.
       
    55      */
       
    56     private JSSecurityManager() {
       
    57     }
       
    58 
       
    59     /** Checks if the VM currently has a SecurityManager installed.
       
    60      * Note that this may change over time. So the result of this method
       
    61      * should not be cached.
       
    62      *
       
    63      * @return true if a SecurityManger is installed, false otherwise.
       
    64      */
       
    65     private static boolean hasSecurityManager() {
       
    66         return (System.getSecurityManager() != null);
       
    67     }
       
    68 
       
    69 
       
    70     static void checkRecordPermission() throws SecurityException {
       
    71         if(Printer.trace) Printer.trace("JSSecurityManager.checkRecordPermission()");
       
    72         SecurityManager sm = System.getSecurityManager();
       
    73         if (sm != null) {
       
    74             sm.checkPermission(new AudioPermission("record"));
       
    75         }
       
    76     }
       
    77 
       
    78 
       
    79     static void loadLibrary(final String libName) {
       
    80         try {
       
    81             if (hasSecurityManager()) {
       
    82                 if(Printer.debug) Printer.debug("using security manager to load library");
       
    83                 PrivilegedAction action = new PrivilegedAction() {
       
    84                         public Object run() {
       
    85                             System.loadLibrary(libName);
       
    86                             return null;
       
    87                         }
       
    88                     };
       
    89                 AccessController.doPrivileged(action);
       
    90             } else {
       
    91                 if(Printer.debug) Printer.debug("not using security manager to load library");
       
    92                 System.loadLibrary(libName);
       
    93             }
       
    94             if (Printer.debug) Printer.debug("loaded library " + libName);
       
    95         } catch (UnsatisfiedLinkError e2) {
       
    96             if (Printer.err)Printer.err("UnsatisfiedLinkError loading native library " + libName);
       
    97             throw(e2);
       
    98         }
       
    99     }
       
   100 
       
   101 
       
   102     static String getProperty(final String propertyName) {
       
   103         String propertyValue;
       
   104         if (hasSecurityManager()) {
       
   105             if(Printer.debug) Printer.debug("using JDK 1.2 security to get property");
       
   106             try{
       
   107                 PrivilegedAction action = new PrivilegedAction() {
       
   108                         public Object run() {
       
   109                             try {
       
   110                                 return System.getProperty(propertyName);
       
   111                             } catch (Throwable t) {
       
   112                                 return null;
       
   113                             }
       
   114                         }
       
   115                     };
       
   116                 propertyValue = (String) AccessController.doPrivileged(action);
       
   117             } catch( Exception e ) {
       
   118                 if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
       
   119                 propertyValue = System.getProperty(propertyName);
       
   120             }
       
   121         } else {
       
   122             if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
       
   123             propertyValue = System.getProperty(propertyName);
       
   124         }
       
   125         return propertyValue;
       
   126     }
       
   127 
       
   128 
       
   129     /** Load properties from a file.
       
   130         This method tries to load properties from the filename give into
       
   131         the passed properties object.
       
   132         If the file cannot be found or something else goes wrong,
       
   133         the method silently fails.
       
   134         @param properties The properties bundle to store the values of the
       
   135         properties file.
       
   136         @param filename The filename of the properties file to load. This
       
   137         filename is interpreted as relative to the subdirectory "lib" in
       
   138         the JRE directory.
       
   139      */
       
   140     static void loadProperties(final Properties properties,
       
   141                                final String filename) {
       
   142         if(hasSecurityManager()) {
       
   143             try {
       
   144                 // invoke the privileged action using 1.2 security
       
   145                 PrivilegedAction action = new PrivilegedAction() {
       
   146                         public Object run() {
       
   147                             loadPropertiesImpl(properties, filename);
       
   148                             return null;
       
   149                         }
       
   150                     };
       
   151                 AccessController.doPrivileged(action);
       
   152                 if(Printer.debug)Printer.debug("Loaded properties with JDK 1.2 security");
       
   153             } catch (Exception e) {
       
   154                 if(Printer.debug)Printer.debug("Exception loading properties with JDK 1.2 security");
       
   155                 // try without using JDK 1.2 security
       
   156                 loadPropertiesImpl(properties, filename);
       
   157             }
       
   158         } else {
       
   159             // not JDK 1.2 security, assume we already have permission
       
   160             loadPropertiesImpl(properties, filename);
       
   161         }
       
   162     }
       
   163 
       
   164 
       
   165     private static void loadPropertiesImpl(Properties properties,
       
   166                                            String filename) {
       
   167         if(Printer.trace)Printer.trace(">> JSSecurityManager: loadPropertiesImpl()");
       
   168         String fname = System.getProperty("java.home");
       
   169         try {
       
   170             if (fname == null) {
       
   171                 throw new Error("Can't find java.home ??");
       
   172             }
       
   173             File f = new File(fname, "lib");
       
   174             f = new File(f, filename);
       
   175             fname = f.getCanonicalPath();
       
   176             InputStream in = new FileInputStream(fname);
       
   177             BufferedInputStream bin = new BufferedInputStream(in);
       
   178             try {
       
   179                 properties.load(bin);
       
   180             } finally {
       
   181                 if (in != null) {
       
   182                     in.close();
       
   183                 }
       
   184             }
       
   185         } catch (Throwable t) {
       
   186             if (Printer.trace) {
       
   187                 System.err.println("Could not load properties file \"" + fname + "\"");
       
   188                 t.printStackTrace();
       
   189             }
       
   190         }
       
   191         if(Printer.trace)Printer.trace("<< JSSecurityManager: loadPropertiesImpl() completed");
       
   192     }
       
   193 
       
   194 
       
   195     private static ThreadGroup getTopmostThreadGroup() {
       
   196         ThreadGroup topmostThreadGroup;
       
   197         if(hasSecurityManager()) {
       
   198             try {
       
   199                 // invoke the privileged action using 1.2 security
       
   200                 PrivilegedAction action = new PrivilegedAction() {
       
   201                         public Object run() {
       
   202                             try {
       
   203                                 return getTopmostThreadGroupImpl();
       
   204                             } catch (Throwable t) {
       
   205                                 return null;
       
   206                             }
       
   207                         }
       
   208                     };
       
   209                 topmostThreadGroup = (ThreadGroup) AccessController.doPrivileged(action);
       
   210                 if(Printer.debug)Printer.debug("Got topmost thread group with JDK 1.2 security");
       
   211             } catch (Exception e) {
       
   212                 if(Printer.debug)Printer.debug("Exception getting topmost thread group with JDK 1.2 security");
       
   213                 // try without using JDK 1.2 security
       
   214                 topmostThreadGroup = getTopmostThreadGroupImpl();
       
   215             }
       
   216         } else {
       
   217             // not JDK 1.2 security, assume we already have permission
       
   218             topmostThreadGroup = getTopmostThreadGroupImpl();
       
   219         }
       
   220         return topmostThreadGroup;
       
   221     }
       
   222 
       
   223 
       
   224     private static ThreadGroup getTopmostThreadGroupImpl() {
       
   225         if(Printer.trace)Printer.trace(">> JSSecurityManager: getTopmostThreadGroupImpl()");
       
   226         ThreadGroup g = Thread.currentThread().getThreadGroup();
       
   227         while ((g.getParent() != null) && (g.getParent().getParent() != null)) {
       
   228             g = g.getParent();
       
   229         }
       
   230         if(Printer.trace)Printer.trace("<< JSSecurityManager: getTopmostThreadGroupImpl() completed");
       
   231         return g;
       
   232     }
       
   233 
       
   234 
       
   235     /** Create a Thread in the topmost ThreadGroup.
       
   236      */
       
   237     static Thread createThread(final Runnable runnable,
       
   238                                final String threadName,
       
   239                                final boolean isDaemon, final int priority,
       
   240                                final boolean doStart) {
       
   241         Thread thread = null;
       
   242         if(hasSecurityManager()) {
       
   243             PrivilegedAction action = new PrivilegedAction() {
       
   244                     public Object run() {
       
   245                         try {
       
   246                             return createThreadImpl(runnable, threadName,
       
   247                                                     isDaemon, priority,
       
   248                                                     doStart);
       
   249                         } catch (Throwable t) {
       
   250                             return null;
       
   251                         }
       
   252                     }
       
   253                 };
       
   254             thread = (Thread) AccessController.doPrivileged(action);
       
   255             if(Printer.debug) Printer.debug("created thread with JDK 1.2 security");
       
   256         } else {
       
   257             if(Printer.debug)Printer.debug("not using JDK 1.2 security");
       
   258             thread = createThreadImpl(runnable, threadName, isDaemon, priority,
       
   259                                       doStart);
       
   260         }
       
   261         return thread;
       
   262     }
       
   263 
       
   264 
       
   265     private static Thread createThreadImpl(Runnable runnable,
       
   266                                            String threadName,
       
   267                                            boolean isDaemon, int priority,
       
   268                                            boolean doStart) {
       
   269         ThreadGroup threadGroup = getTopmostThreadGroupImpl();
       
   270         Thread thread = new Thread(threadGroup, runnable);
       
   271         if (threadName != null) {
       
   272             thread.setName(threadName);
       
   273         }
       
   274         thread.setDaemon(isDaemon);
       
   275         if (priority >= 0) {
       
   276             thread.setPriority(priority);
       
   277         }
       
   278         if (doStart) {
       
   279             thread.start();
       
   280         }
       
   281         return thread;
       
   282     }
       
   283 
       
   284 
       
   285     static List getProviders(final Class providerClass) {
       
   286         PrivilegedAction action = new PrivilegedAction() {
       
   287                 public Object run() {
       
   288                     List p = new ArrayList();
       
   289                     Iterator ps = Service.providers(providerClass);
       
   290                     while (ps.hasNext()) {
       
   291                         try {
       
   292                             Object provider = ps.next();
       
   293                             if (providerClass.isInstance(provider)) {
       
   294                                 // $$mp 2003-08-22
       
   295                                 // Always adding at the beginning reverses the
       
   296                                 // order of the providers. So we no longer have
       
   297                                 // to do this in AudioSystem and MidiSystem.
       
   298                                 p.add(0, provider);
       
   299                             }
       
   300                         } catch (Throwable t) {
       
   301                             //$$fb 2002-11-07: do not fail on SPI not found
       
   302                             if (Printer.err) t.printStackTrace();
       
   303                         }                                                                  }
       
   304                     return p;
       
   305                 }
       
   306             };
       
   307         List providers = (List) AccessController.doPrivileged(action);
       
   308         return providers;
       
   309     }
       
   310 }