All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.enterprise.admin.cli.cluster.ChangeNodeMasterPasswordCommand Maven / Gradle / Ivy

There is a newer version: 4.1.2.181
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2013 Oracle and/or its affiliates. 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
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  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 at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [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, 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.
 */

// Portions Copyright [2016] [Payara Foundation]


package com.sun.enterprise.admin.cli.cluster;

import com.sun.enterprise.admin.servermgmt.NodeKeystoreManager;
import com.sun.enterprise.admin.servermgmt.RepositoryConfig;
import com.sun.enterprise.admin.util.CommandModelData.ParamModelData;
import com.sun.enterprise.security.store.PasswordAdapter;
import com.sun.enterprise.universal.i18n.LocalStringsImpl;
import com.sun.enterprise.universal.xml.MiniXmlParser;
import com.sun.enterprise.universal.xml.MiniXmlParserException;
import com.sun.enterprise.util.HostAndPort;
import org.glassfish.api.Param;
import org.glassfish.api.admin.CommandException;

import org.glassfish.security.common.FileProtectionUtility;
import org.jvnet.hk2.annotations.Service;
import org.glassfish.hk2.api.PerLookup;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;

/**
 * The change-master-password command for a node.
 * It takes in a nodeDir and node name
 *
 * @author Bhakti Mehta
 */
@Service(name = "_change-master-password-node")
@PerLookup

public  class ChangeNodeMasterPasswordCommand extends LocalInstanceCommand {

    @Param(name = "nodedir", optional = true)
    protected String nodeDir0;           // nodeDirRoot

    @Param(name = "node", primary = true)
    protected String node0;

    @Param(name = "savemasterpassword", optional = true, defaultValue = "false")
    protected boolean savemp;

    private static final String MASTER_PASSWORD_ALIAS="master-password";

    private static final LocalStringsImpl strings =
            new LocalStringsImpl(ChangeNodeMasterPasswordCommand.class);

    private String newPassword;

    private String oldPassword;


    @Override
    protected int executeCommand() throws CommandException {

        try {
            nodeDir = nodeDir0;
            node = node0;
            File serverDir = new File(nodeDir,node);

            if (!serverDir.isDirectory()) {
                throw new CommandException(strings.get("bad.node.dir",serverDir));
            }

            ArrayList serverNames = getInstanceDirs(serverDir);
            for (String serverName: serverNames) 
                if (isRunning(serverDir, serverName))
                    throw new CommandException(strings.get("instance.is.running",
                            serverName));

            oldPassword = passwords.get("AS_ADMIN_MASTERPASSWORD");
            if (oldPassword == null) {
                oldPassword = super.readPassword(strings.get("old.mp"));
            }
            if (oldPassword == null)
                throw new CommandException(strings.get("no.console"));

            // for each instance iterate through the instances first,
            // read each keystore with the old password,
            // only then should it save the new master password.
            boolean valid = true;
            for(String instanceDir0: getInstanceDirs(nodeDirChild)) {
               valid &= verifyInstancePassword(new File(nodeDirChild,instanceDir0));
           }
           if (!valid) {
               throw new CommandException(strings.get("incorrect.old.mp"));
           }
            ParamModelData nmpo = new ParamModelData("AS_ADMIN_NEWMASTERPASSWORD",
                    String.class, false, null);
            nmpo.prompt = strings.get("new.mp");
            nmpo.promptAgain = strings.get("new.mp.again");
            nmpo.param._password = true;
            newPassword = super.getPassword(nmpo, null, true);

            // for each instance encrypt the keystore
            for(String instanceDir2: getInstanceDirs(nodeDirChild)) {
               encryptKeystore(instanceDir2);
           }
            if (savemp) {
                createMasterPasswordFile();
            }
            return 0;
        } catch(Exception e) {
            throw new CommandException(e.getMessage(),e);
        }
    }

    /**
     * This will load and verify the keystore for each of the instances
     * in a node
     * @param instanceDir0 The instance directory
     * @return  if the password is valid for the instance keystore
     */
    private boolean verifyInstancePassword(File instanceDir) {

        File mp = new File(new File(instanceDir, "config"), "cacerts.jks");
        return loadAndVerifyKeystore(mp,oldPassword);
    }



    @Override
    public int execute(String... argv) throws CommandException {
        // We iterate through all the instances and so it should relax this requirement
        // that there is only 1 instance in a node .
        checkOneAndOnly = false;
        return super.execute(argv);
    }

    /**
     * Create the master password keystore. This routine can also modify the master password
     * if the keystore already exists
     *
     * @throws CommandException
     */
    protected void createMasterPasswordFile() throws CommandException {
        final File pwdFile = new File(this.getServerDirs().getAgentDir(), MASTER_PASSWORD_ALIAS);
        try {
            PasswordAdapter p = new PasswordAdapter(pwdFile.getAbsolutePath(),
                MASTER_PASSWORD_ALIAS.toCharArray());
            p.setPasswordForAlias(MASTER_PASSWORD_ALIAS, newPassword.getBytes());
            FileProtectionUtility.chmod0600(pwdFile);
        } catch (Exception ex) {
            throw new CommandException(strings.get("masterPasswordFileNotCreated", pwdFile),
                ex);
        }
    }


    /*
     * This will encrypt the keystore
     */
    public void encryptKeystore(String f) throws CommandException {

        RepositoryConfig nodeConfig = new RepositoryConfig(f,
                new File(nodeDir, node).toString(), f);
        NodeKeystoreManager km = new NodeKeystoreManager();
        try {
            km.encryptKeystore(nodeConfig,oldPassword,newPassword);

        } catch (Exception e) {
             throw new CommandException(strings.get("Keystore.not.encrypted"),
                e);
        }

    }

    /**
     * This will get all the instances for a given node
     * @param parent  node
     * @return   The list of instances for a node
     * @throws CommandException
     */
    private ArrayList getInstanceDirs(File parent) throws CommandException {

         ArrayList instancesList = new ArrayList();
         File[] files = parent.listFiles(new FileFilter() {
             public boolean accept(File f) {
                 return f.isDirectory();
             }
         });

         if (files == null || files.length == 0) {
             throw new CommandException(
                     strings.get("Instance.noInstanceDirs", parent));
         }

         for (File f : files) {
             if (!f.getName().equals("agent"))
                 instancesList.add(f.getName());
         }
         return instancesList;

     }

    private boolean isRunning(File nodeDirChild, String serverName)
            throws CommandException {
        try {
            File serverDir = new File(nodeDirChild, serverName);
            File configDir = new File(serverDir, "config");
            File domainXml = new File(configDir, "domain.xml");
            if (!domainXml.exists())
                return false;
            MiniXmlParser parser = new MiniXmlParser(domainXml, serverName);
            List addrSet = parser.getAdminAddresses();
            if (addrSet.size() <= 0)
                throw new CommandException(strings.get("NoAdminPort"));
            HostAndPort addr = addrSet.get(0);
            return isRunning(addr.getHost(), addr.getPort());
        } catch (MiniXmlParserException ex) {
            throw new CommandException(strings.get("NoAdminPortEx", ex), ex);
        }
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy