Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.java
38867 views
/*1* Copyright (c) 2003, 2004, 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.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22import sun.management.jmxremote.ConnectorBootstrap;2324import java.io.File;25import java.io.FileInputStream;26import java.io.InputStream;27import java.io.FilenameFilter;28import java.io.IOException;2930import java.security.GeneralSecurityException;31import java.security.KeyStore;3233import java.util.Properties;34import java.util.Iterator;35import java.util.Set;36import java.util.Arrays;37import java.util.ArrayList;38import java.util.HashMap;39import java.util.Map;40import java.util.Enumeration;4142import javax.management.remote.*;43import javax.management.*;4445import sun.management.AgentConfigurationError;4647import util.TestLogger;4849/**50* <p>This class implements unit test for RMI Bootstrap.51* When called with no arguments main() looks in the directory indicated52* by the "test.src" system property for files called management*ok.properties53* or management*ko.properties. The *ok.properties files are assumed to be54* valid Java M&M config files for which the bootstrap should succeed.55* The *ko.properties files are assumed to be configurations for which the56* bootstrap & connection test will fail.</p>57*58* <p>The rmi port number can be specified with the "rmi.port" system property.59* If not, this test will use 12424</p>60*61* <p>When called with some argument, the main() will interprete its args to62* be Java M&M configuration file names. The filenames are expected to end63* with ok.properties or ko.properties - and are interpreted as above.</p>64*65* <p>Note that a limitation of the RMI registry (bug 4267864) prevent66* this test from succeeding if more than 1 configuration is used.67* As long as 4267864 isn't fix, this test must be called as many times68* as needed but with a single argument (no arguments, or several arguments69* will fail).</p>70*71* <p>Debug traces are logged in "sun.management.test"</p>72**/73public class RmiSslNoKeyStoreTest {7475static TestLogger log =76new TestLogger("RmiSslNoKeyStoreTest");7778/**79* When launching several registries, we increment the port number80* to avoid falling into "port number already in use" problems.81**/82static int testPort = 0;8384/**85* Default values for RMI configuration properties.86**/87public static interface DefaultValues {88public static final String PORT="0";89public static final String CONFIG_FILE_NAME="management.properties";90public static final String USE_SSL="true";91public static final String USE_AUTHENTICATION="true";92public static final String PASSWORD_FILE_NAME="jmxremote.password";93public static final String ACCESS_FILE_NAME="jmxremote.access";94public static final String KEYSTORE="keystore";95public static final String KEYSTORE_PASSWD="password";96public static final String TRUSTSTORE="truststore";97public static final String TRUSTSTORE_PASSWD="trustword";98}99100/**101* Names of RMI configuration properties.102**/103public static interface PropertyNames {104public static final String PORT="com.sun.management.jmxremote.port";105public static final String CONFIG_FILE_NAME=106"com.sun.management.config.file";107public static final String USE_SSL="com.sun.management.jmxremote.ssl";108public static final String USE_AUTHENTICATION=109"com.sun.management.jmxremote.authenticate";110public static final String PASSWORD_FILE_NAME=111"com.sun.management.jmxremote.password.file";112public static final String ACCESS_FILE_NAME=113"com.sun.management.jmxremote.access.file";114public static final String INSTRUMENT_ALL=115"com.sun.management.instrumentall";116public static final String CREDENTIALS =117"jmx.remote.credentials";118public static final String KEYSTORE="javax.net.ssl.keyStore";119public static final String KEYSTORE_PASSWD=120"javax.net.ssl.keyStorePassword";121public static final String KEYSTORE_TYPE="javax.net.ssl.keyStoreType";122public static final String TRUSTSTORE="javax.net.ssl.trustStore";123public static final String TRUSTSTORE_PASSWD=124"javax.net.ssl.trustStorePassword";125}126127/**128* Compute the full path name for a default file.129* @param basename basename (with extension) of the default file.130* @return ${JRE}/lib/management/${basename}131**/132private static String getDefaultFileName(String basename) {133final String fileSeparator = File.separator;134final StringBuffer defaultFileName =135new StringBuffer(System.getProperty("java.home")).136append(fileSeparator).append("lib").append(fileSeparator).137append("management").append(fileSeparator).138append(basename);139return defaultFileName.toString();140}141142/**143* Compute the full path name for a default file.144* @param basename basename (with extension) of the default file.145* @return ${JRE}/lib/management/${basename}146**/147private static String getDefaultStoreName(String basename) {148final String fileSeparator = File.separator;149final StringBuffer defaultFileName =150new StringBuffer(System.getProperty("test.src")).151append(fileSeparator).append("ssl").append(fileSeparator).152append(basename);153return defaultFileName.toString();154}155156private static void checkKeystore(Properties props)157throws IOException, GeneralSecurityException {158if (log.isDebugOn())159log.debug("checkKeystore","Checking Keystore configuration");160161final String keyStore =162System.getProperty(PropertyNames.KEYSTORE);163if (keyStore == null)164throw new IllegalArgumentException("System property " +165PropertyNames.KEYSTORE +166" not specified");167168final String keyStorePass =169System.getProperty(PropertyNames.KEYSTORE_PASSWD);170if (keyStorePass == null) {171// We don't have the password, we can only check whether the172// file exists...173//174final File ksf = new File(keyStore);175if (! ksf.canRead())176throw new IOException(keyStore + ": not readable");177178if (log.isDebugOn())179log.debug("checkSSL", "No password.");180throw new IllegalArgumentException("System property " +181PropertyNames.KEYSTORE_PASSWD +182" not specified");183}184185// Now we're going to load the keyStore - just to check it's186// correct.187//188final String keyStoreType =189System.getProperty(PropertyNames.KEYSTORE_TYPE,190KeyStore.getDefaultType());191final KeyStore ks = KeyStore.getInstance(keyStoreType);192final FileInputStream fin = new FileInputStream(keyStore);193final char keypassword[] = keyStorePass.toCharArray();194195try {196ks.load(fin,keypassword);197} finally {198Arrays.fill(keypassword,' ');199fin.close();200}201202if (log.isDebugOn())203log.debug("checkSSL","SSL configuration successfully checked");204}205206private void checkSslConfiguration() throws Exception {207final String defaultConf =208getDefaultFileName(DefaultValues.CONFIG_FILE_NAME);209final String confname =210System.getProperty(PropertyNames.CONFIG_FILE_NAME,defaultConf);211212final Properties props = new Properties();213final File conf = new File(confname);214if (conf.exists()) {215FileInputStream fin = new FileInputStream(conf);216try {props.load(fin);} finally {fin.close();}217}218219// Do we use SSL?220final String useSslStr =221props.getProperty(PropertyNames.USE_SSL,222DefaultValues.USE_SSL);223final boolean useSsl =224Boolean.valueOf(useSslStr).booleanValue();225226log.debug("checkSslConfiguration",PropertyNames.USE_SSL+"="+useSsl);227if (useSsl == false) {228final String msg =229PropertyNames.USE_SSL+"="+useSsl+", can't run test";230throw new IllegalArgumentException(msg);231}232233try {234checkKeystore(props);235} catch (Exception x) {236// Ok!237log.debug("checkSslConfiguration","Test configuration OK: " + x);238return;239}240241final String msg = "KeyStore properly configured, can't run test";242throw new IllegalArgumentException(msg);243}244245/**246* Test the configuration indicated by `file'.247* Sets the appropriate System properties for config file and248* port and then calls ConnectorBootstrap.initialize().249* eventually cleans up by calling ConnectorBootstrap.terminate().250* @return null if the test succeeds, an error message otherwise.251**/252private String testConfiguration(File file,int port) {253254final String path = (file==null)?null:file.getAbsolutePath();255final String config = (path==null)?"Default config file":path;256257try {258System.out.println("***");259System.out.println("*** Testing configuration (port="+260port + "): "+ path);261System.out.println("***");262263System.setProperty("com.sun.management.jmxremote.port",264Integer.toString(port));265if (path != null)266System.setProperty("com.sun.management.config.file", path);267else268System.getProperties().269remove("com.sun.management.config.file");270271log.trace("testConfiguration","com.sun.management.jmxremote.port="+port);272if (path != null && log.isDebugOn())273log.trace("testConfiguration",274"com.sun.management.config.file="+path);275276checkSslConfiguration();277278final JMXConnectorServer cs;279try {280cs = ConnectorBootstrap.initialize();281} catch (AgentConfigurationError x) {282final String err = "Failed to initialize connector:" +283"\n\tcom.sun.management.jmxremote.port=" + port +284((path!=null)?"\n\tcom.sun.management.config.file="+path:285"\n\t"+config) +286"\n\tError is: " + x;287288log.trace("testConfiguration","Expected failure: " + err);289log.debug("testConfiguration",x);290System.out.println("Got expected failure: " + x);291return null;292} catch (Exception x) {293log.debug("testConfiguration",x);294return x.toString();295}296try {297JMXConnector cc =298JMXConnectorFactory.connect(cs.getAddress(), null);299cc.close();300} catch (IOException x) {301final String err = "Failed to initialize connector:" +302"\n\tcom.sun.management.jmxremote.port=" + port +303((path!=null)?"\n\tcom.sun.management.config.file="+path:304"\n\t"+config) +305"\n\tError is: " + x;306307log.trace("testConfiguration","Expected failure: " + err);308log.debug("testConfiguration",x);309System.out.println("Got expected failure: " + x);310return null;311} catch (Exception x) {312log.debug("testConfiguration",x);313return x.toString();314}315try {316cs.stop();317} catch (Exception x) {318final String err = "Failed to terminate: "+x;319log.trace("testConfiguration",err);320log.debug("testConfiguration",x);321}322final String err = "Bootstrap should have failed:" +323"\n\tcom.sun.management.jmxremote.port=" + port +324((path!=null)?"\n\tcom.sun.management.config.file="+path:325"\n\t"+config);326log.trace("testConfiguration",err);327return err;328} catch (Exception x) {329final String err = "Failed to test bootstrap for:" +330"\n\tcom.sun.management.jmxremote.port=" + port +331((path!=null)?"\n\tcom.sun.management.config.file="+path:332"\n\t"+config)+333"\n\tError is: " + x;334335log.trace("testConfiguration",err);336log.debug("testConfiguration",x);337return err;338}339}340341/**342* Test a configuration file. Determines whether the bootstrap343* should succeed or fail depending on the file name:344* *ok.properties: bootstrap should succeed.345* *ko.properties: bootstrap or connection should fail.346* @return null if the test succeeds, an error message otherwise.347**/348private String testConfigurationFile(String fileName) {349File file = new File(fileName);350final String portStr = System.getProperty("rmi.port","12424");351final int port = Integer.parseInt(portStr);352353return testConfiguration(file,port+testPort++);354}355356357/**358* Tests the specified configuration files.359* If args[] is not empty, each element in args[] is expected to be360* a filename ending either by ok.properties or ko.properties.361* Otherwise, the configuration files will be automatically determined362* by looking at all *.properties files located in the directory363* indicated by the System property "test.src".364* @throws RuntimeException if the test fails.365**/366public void run(String args[]) {367final String defaultKeyStore =368getDefaultStoreName(DefaultValues.KEYSTORE);369final String keyStore =370System.getProperty(PropertyNames.KEYSTORE, defaultKeyStore);371372for (int i=0; i<args.length; i++) {373374String errStr =testConfigurationFile(args[i]);375if (errStr != null) {376throw new RuntimeException(errStr);377}378379if ((System.getProperty(PropertyNames.KEYSTORE) == null) &&380(System.getProperty(PropertyNames.KEYSTORE_PASSWD) == null)) {381try {382383// Specify the keystore, but don't specify the384// password.385//386System.setProperty(PropertyNames.KEYSTORE,keyStore);387log.trace("run",PropertyNames.KEYSTORE+"="+keyStore);388389errStr =testConfigurationFile(args[i]);390if (errStr != null) {391throw new RuntimeException(errStr);392}393} finally {394System.getProperties().remove(PropertyNames.KEYSTORE);395}396}397}398}399400/**401* Calls run(args[]).402* exit(1) if the test fails.403**/404public static void main(String args[]) {405RmiSslNoKeyStoreTest manager = new RmiSslNoKeyStoreTest();406try {407manager.run(args);408} catch (RuntimeException r) {409System.err.println("Test Failed: "+ r.getMessage());410System.exit(1);411} catch (Throwable t) {412System.err.println("Test Failed: "+ t);413t.printStackTrace();414System.exit(2);415}416System.out.println("**** Test RmiSslNoKeyStoreTest Passed ****");417}418419}420421422