📄 security.java
字号:
/* * @(#)Security.java 1.110 06/10/11 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */package java.security;import java.lang.reflect.*;import java.util.*;import java.io.*;import java.net.URL;import java.security.InvalidParameterException;import sun.security.util.Debug;import sun.security.util.PropertyExpander;/** * <p>This class centralizes all security properties and common security * methods. One of its primary uses is to manage providers. * * @author Benjamin Renaud * @version 1.101 10/17/00 */public final class Security { // Do providers need to be reloaded? private static boolean reloadProviders = true; /* Are we debugging? -- for developers */ static final boolean debug = false; private static final Debug sdebug = Debug.getInstance("properties"); /* Are we displaying errors? -- for users */ static final boolean error = true; /* The java.security properties */ private static Properties props; /* A vector of providers, in order of priority */ private static Vector providers; // Where we cache provider properties private static Hashtable providerPropertiesCache; // Where we cache engine provider properties private static Hashtable engineCache; // Where we cache search results private static Hashtable searchResultsCache; // providers currently attempting to be loaded private static Hashtable providerLoads; // An element in the cache private static class ProviderProperty { String className; Provider provider; } // Number of statically registered security providers. No duplicates. private static int numOfStaticProviders = 0; /* A vector of statically registered providers' master class names, * in order of priority. No duplicates. */ private static Vector providerMasterClassNames = new Vector(6); // Index for the vector providerMasterClassNames. // It points to the next provider which we should try to load. private static int indexStaticProviders = 0; // Does the indexStaticProviders need to be reset? private static boolean resetProviderIndex = false; static { // doPrivileged here because there are multiple // things in initialize that might require privs. // (the FileInputStream call and the File.exists call, // the securityPropFile call, etc) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { initialize(); return null; } }); } private static void initialize() { props = new Properties(); providers = new Vector(); providerPropertiesCache = new Hashtable(); engineCache = new Hashtable(); searchResultsCache = new Hashtable(5); providerLoads = new Hashtable(1); boolean loadedProps = false; boolean overrideAll = false; // first load the system properties file // to determine the value of security.overridePropertiesFile File propFile = securityPropFile("java.security"); if (propFile.exists()) { try { FileInputStream is = new FileInputStream(propFile); // Inputstream has been buffered in Properties class props.load(is); is.close(); loadedProps = true; if (sdebug != null) { sdebug.println("reading security properties file: " + propFile); } } catch (IOException e) { if (sdebug != null) { sdebug.println("unable to load security properties from " + propFile); e.printStackTrace(); } } } if ("true".equalsIgnoreCase(props.getProperty ("security.overridePropertiesFile"))) { String extraPropFile = System.getProperty ("java.security.properties"); if (extraPropFile != null && extraPropFile.startsWith("=")) { overrideAll = true; extraPropFile = extraPropFile.substring(1); } if (overrideAll) { props = new Properties(); if (sdebug != null) { sdebug.println ("overriding other security properties files!"); } } // now load the user-specified file so its values // will win if they conflict with the earlier values if (extraPropFile != null) { try { URL propURL; extraPropFile = PropertyExpander.expand(extraPropFile); propFile = new File(extraPropFile); if (propFile.exists()) { propURL = new URL ("file:" + propFile.getCanonicalPath()); } else { propURL = new URL(extraPropFile); } BufferedInputStream bis = new BufferedInputStream (propURL.openStream()); props.load(bis); bis.close(); loadedProps = true; if (sdebug != null) { sdebug.println("reading security properties file: " + propURL); if (overrideAll) { sdebug.println ("overriding other security properties files!"); } } } catch (Exception e) { if (sdebug != null) { sdebug.println ("unable to load security properties from " + extraPropFile); e.printStackTrace(); } } } } if (!loadedProps) { initializeStatic(); if (sdebug != null) { sdebug.println("unable to load security properties " + "-- using defaults"); } } // Not loading providers here. Just counts how many providers // are statically registered. This reduces the startup // footprint. countProviders(); } /* * Initialize to default values, if <java.home>/lib/java.security * is not found. */ private static void initializeStatic() { props.put("security.provider.1", "sun.security.provider.Sun"); } /** * Don't let anyone instantiate this. */ private Security() { } /** * Loops through provider declarations, which are expected to be * of the form: * * security.provider.1=sun.security.provider.Sun * security.provider.2=sun.security.jsafe.Jsafe * etc. * * The order determines the default search order when looking for * an algorithm. */ private static synchronized void countProviders() { int i = 1; while (true) { String name = props.getProperty("security.provider." + i); if (name == null) { break; } else { String fullClassName = name.trim(); if (fullClassName.length() == 0) { System.err.println("invalid entry for " + "security.provider." + i); break; } else { // Get rid of duplicate providers. if (!providerMasterClassNames.contains(fullClassName)) { providerMasterClassNames.add(fullClassName); } i++; } } } // Get the number of statically registered providers. numOfStaticProviders = providerMasterClassNames.size(); } /* * Reload the providers (provided as extensions) that could not be loaded * (because there was no system class loader available) when this class * was initialized. */ private static synchronized void reloadProviders() { if (reloadProviders) { sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); if (l != null) { synchronized (Security.class) { reloadProviders = false; // We don't want loadOneMoreProvider() to do // anything from now on since this method will // load all static providers. indexStaticProviders = numOfStaticProviders; resetProviderIndex = false; providers.removeAllElements(); // i is an index for the vector // providerMasterClassNames. So it starts from 0. int i = 0; while (i < numOfStaticProviders) { final String name = (String)providerMasterClassNames.elementAt(i); i++; Provider prov = (Provider)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return Provider.loadProvider(name); } }); if (prov != null) { providers.addElement(prov); } } // empty provider-property cache providerPropertiesCache.clear(); engineCache.clear(); searchResultsCache.clear(); } } } } /** * Try our best to load one more statically registered provider. * This is used by getEngineClassName(String algName, String engineType). */ private static synchronized void loadOneMoreProvider() { // suspend provider reloading inside this method boolean restore = false; if (reloadProviders) { restore = true; reloadProviders = false; } try { sun.misc.Launcher l = sun.misc.Launcher.getLauncher(); /* * Even if the launcher l is null, we still want to * load providers if we can. See bug 4418903. * When we first see that the launcher isn't null, we * could be in one of the following situations: * a) some providers were loaded out of the priority order. * For example, 6 providers are statically configured, and * provider 2 and 4 are loaded. The field resetProviderIndex * should be "true". So we can try to load providers * according to the priority order when the launcher isn't null. * b) some providers were loaded, but not out of order. * For example, 6 providers are statically configured, and * provider 1 and 2 are loaded. The field resetProviderIndex * should be "false". So we just try to load the next * provider whose index is indexStaticProviders. * c) no providers were loaded. The field resetProviderIndex * should be "false". So we just try to load the first * provider. Note: indexStaticProviders is 0 in this case. */ if (indexStaticProviders >= numOfStaticProviders) { return; } Provider prov = null; while (indexStaticProviders < numOfStaticProviders) { final String name = (String)providerMasterClassNames.elementAt( indexStaticProviders); // determine if the loadProvider call below is looping. // this may occur if the provider to be loaded is signed. // if looping, continue if (providerLoads.get(name) != null) { indexStaticProviders++; continue; } else { providerLoads.put(name, name); } prov = (Provider)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return Provider.loadProvider(name); } }); // indexStaticProviders points to the next provider we // should try to load. indexStaticProviders++; providerLoads.remove(name); if (prov != null) { /* This must manipulate the datastructure directly, because going through addProviders causes a security check to happen, which sometimes will cause the security initialization to fail with bad consequences. */ providers.addElement(prov); // empty provider-property cache providerPropertiesCache.clear(); engineCache.clear(); searchResultsCache.clear(); break; } else { if (l == null) { // Set resetProviderIndex to true since we may load // providers out of the priority order. resetProviderIndex = true; } } } } finally { // resume provider reloading if necessary if (restore) { reloadProviders = true; } } } private static File securityPropFile(String filename) { // maybe check for a system property which will specify where to // look. Someday. String sep = File.separator; return new File(System.getProperty("java.home") + sep + "lib" + sep + "security" + sep + filename); } /** * Looks up providers, and returns the property (and its associated
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -