Package com.sun.jmx.remote.opt.security

Source Code of com.sun.jmx.remote.opt.security.JMXPasswordAuthenticator

/*
* @(#)JMXPasswordAuthenticator.java  1.3
*
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
*
* The contents of this file are subject to the terms of either the GNU General
* Public License Version 2 only ("GPL") or the Common Development and
* Distribution License("CDDL")(collectively, the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy of the
* License at http://opendmk.dev.java.net/legal_notices/licenses.txt or in the
* LEGAL_NOTICES folder that accompanied this code. See the License for the
* specific language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file found at
*     http://opendmk.dev.java.net/legal_notices/licenses.txt
* or in the LEGAL_NOTICES folder that accompanied this code.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.
*
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
*
*       "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding
*
*       "[Contributor] elects to include this software in this distribution
*        under the [CDDL or GPL Version 2] license."
*
* If you don't indicate a single choice of license, a recipient has the option
* to distribute your version of this file under either the CDDL or the GPL
* Version 2, or to extend the choice of license to its licensees as provided
* above. However, if you add GPL Version 2 code and therefore, elected the
* GPL Version 2 license, then the option applies only if the new code is made
* subject to such option by the copyright holder.
*
*/

package com.sun.jmx.remote.opt.security;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Properties;
import javax.management.remote.JMXPrincipal;
import javax.management.remote.JMXAuthenticator;
import javax.security.auth.Subject;
import com.sun.jmx.remote.opt.util.ClassLogger;

/**
* <p>This class represents a username/password based implementation of
* the {@link JMXAuthenticator} interface.</p>
*
* <p>The set of username/password pairs is passed either as a
* filename which denotes a properties file on disk, or directly as an
* instance of the {@link Properties} class.  In both cases, the name
* of each property represents a username, and the value of the
* property is the associated password.  Thus, any given username
* either does not exist in the properties or has exactly one
* password.  The same password can be shared by several
* usernames.</p>
*
* <p>If authentication is successful then an authenticated {@link Subject}
* filled in with a {@link JMXPrincipal} is returned.  Authorization checks
* will then be performed based on this <code>Subject</code>.</p>
*/
public class JMXPasswordAuthenticator implements JMXAuthenticator {

    /**
     * Creates an instance of <code>JMXPasswordAuthenticator</code>
     * and initializes it from the specified properties file.
     *
     * @param pwFile name of the file which denotes a properties
     * file on disk containing the username/password entries.
     *
     * @exception IOException if the file does not exist, is a
     * directory rather than a regular file, or for some other
     * reason cannot be opened for reading.
     */
    public JMXPasswordAuthenticator(String pwFile) throws IOException {
  this.pwFile = pwFile;
  props = propertiesFromFile(pwFile);
    }

    /**
     * Creates an instance of <code>JMXPasswordAuthenticator</code>
     * and initializes it from the specified properties instance.
     * This constructor makes a copy of the properties instance using
     * its <code>clone</code> method and it is the copy that is
     * consulted to check the username and password of an incoming
     * connection.  The original properties object can be modified
     * without affecting the copy.  If the {@link #refresh} method is
     * then called, the authenticator will make a new copy of the
     * properties object at that time.
     *
     * @param pwProps properties list containing the username/password
     * entries.
     *
     * @exception IllegalArgumentException if <code>pwProps</code> is
     * null.
     */
    public JMXPasswordAuthenticator(Properties pwProps) {
  if (pwProps == null)
      throw new IllegalArgumentException("Null properties");
  originalProps = pwProps;
  props = (Properties) pwProps.clone();
    }

    /**
     * Authenticate the <code>MBeanServerConnection</code> client
     * with the given client credentials.
     *
     * @param credentials the user-defined credentials to be passed in
     * to the server in order to authenticate the user before creating
     * the <code>MBeanServerConnection</code>.  This parameter must
     * be a two-element <code>String[]</code> containing the client's
     * username and password in that order.
     *
     * @return the authenticated subject containing a
     * <code>JMXPrincipal(username)</code>.
     *
     * @exception SecurityException if the server cannot authenticate the user
     * with the provided credentials.
     */
    public Subject authenticate(Object credentials) {
  // Verify that credentials is of type String[].
  //
  if (!(credentials instanceof String[])) {
      // Special case for null so we get a more informative message
      if (credentials == null)
    authenticationFailure("authenticate", "Credentials required");

      final String message =
    "Credentials should be String[] instead of " +
    ((credentials == null) ? "null" :
     credentials.getClass().getName());
      authenticationFailure("authenticate", message);
  }
  // Verify that the array contains two elements.
  //
  final String[] aCredentials = (String[]) credentials;
  if (aCredentials.length != 2) {
      final String message =
    "Credentials should have 2 elements not " +
    aCredentials.length;
      authenticationFailure("authenticate", message);
  }
  // Verify that username exists and the associated
  // password matches the one supplied by the client.
  //
  final String username = (String) aCredentials[0];
  final String password = (String) aCredentials[1];
  if (username == null || password == null) {
      final String message = "Username or password is null";
      authenticationFailure("authenticate", message);
  }
  String localPasswd;
  synchronized (props) {
      localPasswd = props.getProperty(username)// can be null
  }
  if (password.equals(localPasswd)) {
      return
    new Subject(true,
          Collections.singleton(new JMXPrincipal(username)),
          Collections.EMPTY_SET,
          Collections.EMPTY_SET);
  } else {
      if (props.containsKey(username)) {
    final String message =
        "Invalid password for username [" + username + "]";
    authenticationFailure("authenticate", message);
      } else {
    final String message = "Invalid username/password";
    authenticationFailure("authenticate", message);
      }
  }
  return null;
    }

    /**
     * <p>Refresh the set of username/password entries.</p>
     *
     * <p>If this instance was created using the {@link
     * #JMXPasswordAuthenticator(String)} constructor to specify a
     * file from which the entries are read, the file is re-read.</p>
     *
     * <p>If this instance was created using the
     * {@link #JMXPasswordAuthenticator(Properties)} constructor
     * then a new copy of the <code>Properties</code> object is made.</p>
     *
     * @exception IOException if the file does not exist, is a
     * directory rather than a regular file, or for some other
     * reason cannot be opened for reading.
     */
    public void refresh() throws IOException {
  synchronized (props) {
      if (pwFile == null)
    props = (Properties) originalProps.clone();
      else
    props = propertiesFromFile(pwFile);
  }
    }

    private static Properties propertiesFromFile(String fname)
  throws IOException {
  FileInputStream fin = new FileInputStream(fname);
  Properties p = new Properties();
  p.load(fin);
  fin.close();
  return p;
    }

    private static void authenticationFailure(String method, String message)
  throws SecurityException {
  final String msg = "Authentication failed! " + message;
  final SecurityException e = new SecurityException(msg);
  logException(method, msg, e);
  throw e;
    }

    private static void logException(String method,
             String message,
             Exception e) {
  if (logger.traceOn()) {
      logger.trace(method, message);
  }
  if (logger.debugOn()) {
      logger.debug(method, e);
  }
    }

    private Properties props;
    private Properties originalProps;
    private String pwFile;
    private static final ClassLogger logger =
  new ClassLogger("javax.management.remote.misc",
      "JMXPasswordAuthenticator");
}
TOP

Related Classes of com.sun.jmx.remote.opt.security.JMXPasswordAuthenticator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.