--- old/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java 2017-10-06 00:40:06.327423998 +0530 +++ new/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java 2017-10-06 00:40:06.219423667 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,17 +27,13 @@ import com.sun.jmx.mbeanserver.GetPropertyAction; import com.sun.jmx.mbeanserver.Util; -import java.io.BufferedInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.FilePermission; import java.io.IOException; import java.security.AccessControlException; import java.security.AccessController; import java.util.Arrays; -import java.util.Hashtable; import java.util.Map; -import java.util.Properties; import javax.security.auth.*; import javax.security.auth.callback.*; @@ -59,10 +55,7 @@ * the access control file for JMX remote management or in a Java security * policy. * - *

The password file comprises a list of key-value pairs as specified in - * {@link Properties}. The key represents a user's name and the value is its - * associated cleartext password. By default, the following password file is - * used: + * By default, the following password file is used: *

  *     ${java.home}/conf/management/jmxremote.password
  * 
@@ -105,6 +98,11 @@ *
if true, this module clears the username and password * stored in the module's shared state after both phases of authentication * (login and commit) have completed.
+ * + *
hashPasswords
+ *
if true, this module replaces each clear text passwords + * with its hash, if present.
+ * * */ public class FileLoginModule implements LoginModule { @@ -135,6 +133,7 @@ private boolean tryFirstPass = false; private boolean storePass = false; private boolean clearPass = false; + private boolean hashPasswords = false; // Authentication status private boolean succeeded = false; @@ -154,7 +153,7 @@ private String passwordFileDisplayName; private boolean userSuppliedPasswordFile; private boolean hasJavaHomePermission; - private Properties userCredentials; + private HashedPasswordManager hashPwdMgr; /** * Initialize this LoginModule. @@ -186,6 +185,8 @@ "true".equalsIgnoreCase((String)options.get("storePass")); clearPass = "true".equalsIgnoreCase((String)options.get("clearPass")); + hashPasswords = + "true".equalsIgnoreCase((String)options.get("hashPasswords")); passwordFile = (String)options.get("passwordFile"); passwordFileDisplayName = passwordFile; @@ -221,17 +222,27 @@ public boolean login() throws LoginException { try { - loadPasswordFile(); + if(hashPwdMgr == null) { + hashPwdMgr = new HashedPasswordManager(passwordFile, hashPasswords); + } else { + hashPwdMgr.loadPasswords(); + } } catch (IOException ioe) { LoginException le = new LoginException( "Error: unable to load the password file: " + passwordFileDisplayName); throw EnvHelp.initCause(le, ioe); - } - - if (userCredentials == null) { - throw new LoginException - ("Error: unable to locate the users' credentials."); + } catch (SecurityException e) { + if (userSuppliedPasswordFile || hasJavaHomePermission) { + throw e; + } else { + final FilePermission fp = + new FilePermission(passwordFileDisplayName, "read"); + AccessControlException ace = new AccessControlException( + "access denied " + fp.toString()); + ace.setStackTrace(e.getStackTrace()); + throw ace; + } } if (logger.debugOn()) { @@ -437,12 +448,7 @@ // get the username and password getUsernamePassword(usePasswdFromSharedState); - String localPassword; - - // userCredentials is initialized in login() - if (((localPassword = userCredentials.getProperty(username)) == null) || - (! localPassword.equals(new String(password)))) { - + if (!hashPwdMgr.authenticate(username, new String(password))) { // username not found or passwords do not match if (logger.debugOn()) { logger.debug("login", "Invalid username or password"); @@ -468,38 +474,6 @@ } } - /* - * Read the password file. - */ - private void loadPasswordFile() throws IOException { - FileInputStream fis; - try { - fis = new FileInputStream(passwordFile); - } catch (SecurityException e) { - if (userSuppliedPasswordFile || hasJavaHomePermission) { - throw e; - } else { - final FilePermission fp = - new FilePermission(passwordFileDisplayName, "read"); - AccessControlException ace = new AccessControlException( - "access denied " + fp.toString()); - ace.setStackTrace(e.getStackTrace()); - throw ace; - } - } - try { - final BufferedInputStream bis = new BufferedInputStream(fis); - try { - userCredentials = new Properties(); - userCredentials.load(bis); - } finally { - bis.close(); - } - } finally { - fis.close(); - } - } - /** * Get the username and password. * This method does not return any value.