com.sun.enterprise.admin.cli.cluster.ChangeNodeMasterPasswordCommand Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of payara-micro Show documentation
Show all versions of payara-micro Show documentation
Micro Distribution of the Payara Project for IBM JDK
/*
* 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