/* * ProActive Parallel Suite(TM): * The Open Source library for parallel and distributed * Workflows & Scheduling, Orchestration, Cloud Automation * and Big Data Analysis on Enterprise Grids & Clouds. * * Copyright (c) 2007 - 2017 ActiveEon * Contact: contact@activeeon.com * * This library is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation: version 3 of * the License. * * 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * If needed, contact us to obtain a release under GPL Version 2 or 3 * or a different license than the AGPL. */ package org.ow2.proactive.jmx; import javax.management.remote.JMXAuthenticator; import javax.security.auth.Subject; import javax.security.auth.login.LoginException; import org.ow2.proactive.authentication.Authentication; import org.ow2.proactive.authentication.crypto.CredData; import org.ow2.proactive.authentication.crypto.Credentials; /** * Class to perform the authentication for the JMX MBean Server. * * @author The ProActive Team * @since ProActive Scheduling 1.0 */ public final class JMXAuthenticatorImpl implements JMXAuthenticator { /** reference to the authentication Object */ private final Authentication authentication; /** extra permission checker */ private final PermissionChecker permissionChecker; /** * Constructor to assign the values to the global variables * * @param authentication the authentication object that is actually used * @param permissionChecker */ public JMXAuthenticatorImpl(final Authentication authentication, PermissionChecker permissionChecker) { this.authentication = authentication; this.permissionChecker = permissionChecker; } /** * This method is automatically called when a JMX client tries to connect to the MBean Server referred * by the connector. * <p> * The only allowed credentials structure provided by the client is Object[] that contains * username/password (String/String) or username/{@link org.ow2.proactive.authentication.crypto.Credentials} * * @return a subject with the username as JMXPrincipal and the role as pubCredentials {@link javax.security.auth.Subject} * @param rawCredentials the credentials provided by the client */ public Subject authenticate(final Object rawCredentials) { // If not an array of object do not give any clues just throw exception if (rawCredentials == null || !(rawCredentials instanceof Object[])) { throw new SecurityException("Invalid credentials"); } final Object[] arr = (Object[]) rawCredentials; if (arr[0] == null || arr[1] == null) { throw new SecurityException("Invalid credentials"); } final String username = arr[0].toString(); Credentials internalCredentials = null; // If username/Credentials if (arr[1] instanceof Credentials) { internalCredentials = (Credentials) arr[1]; // If username/password (ex: JConsole) } else if (arr[1] instanceof String) { try { internalCredentials = Credentials.createCredentials(new CredData(CredData.parseLogin(username), CredData.parseDomain(username), (String) arr[1]), authentication.getPublicKey()); } catch (Exception e) { throw new SecurityException("Invalid credentials", e); } } else { throw new SecurityException("Invalid credentials"); } try { Subject s = this.authentication.authenticate(internalCredentials); if (permissionChecker != null) { boolean allowed = permissionChecker.checkPermission(internalCredentials); if (!allowed) { throw new SecurityException("Permission denied"); } } return s; } catch (LoginException e) { throw new SecurityException("Unable to authenticate " + username); } } }