Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ InvalidCredentials=Authorization has been refused for credentials [user: {0}] gi

#Error Messages
PasswordLimit=CLI128: Value for {0} must have 8 or more characters.
InvalidCharInDomain=CLI129: Invalid character in domain name, {0}
CouldNotCreateDomain=CLI130: Could not create domain, {0}
InvalidCharInDomain=CLI129: Invalid character in domain name: {0}
CouldNotCreateDomain=CLI130: Could not create domain named {0}
InvalidPortNumber=CLI136: Port {0} should be a numeric value.
InvalidDomainPath=CLI138: Invalid domain path, {0}
CouldNotDeleteDomain=CLI139: Could not delete domain, {0}.
InvalidDomainPath=CLI138: Invalid domain path: {0}
CouldNotDeleteDomain=CLI139: Could not delete domain named {0}.
NoDomainsToList=CLI141: No Domains to list.
NoDomains=CLI142: No domains in {0}.
FileDoesNotExist=CLI146: {0} does not exist in the file system or read permission denied.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,32 @@ protected PEFileLayout getFileLayout(RepositoryConfig config) {
* @throws DomainException
*/
protected void createKeyStore(File keyStore, RepositoryConfig config, String masterPassword) throws DomainException {
if (keyStore.exists()) {
// keystore shouldn't exist in the template, all keys should be domain specific
throw new DomainException(_strMgr.getString("KeystoreShouldntExist", keyStore.getName()));
}

// Generate a new self signed certificate with s1as as the alias
// Create the default self signed cert
final String dasCertDN = getDASCertDN(config);
System.out.println(_strMgr.getString("CertificateDN", dasCertDN));
String keyToolOutput;
try {
final KeyTool keyTool = new KeyTool(keyStore, masterPassword.toCharArray());
keyTool.generateKeyPair(CERTIFICATE_ALIAS, dasCertDN, "RSA", 3650);

// Generate a new self signed certificate with glassfish-instance as the alias
// Create the default self-signed cert for instances to use for SSL auth.
final String instanceCertDN = getInstanceCertDN(config);
keyTool.generateKeyPair(INSTANCE_SECURE_ADMIN_ALIAS, instanceCertDN, "RSA", 3650);
keyToolOutput = keyTool.generateKeyPair(INSTANCE_SECURE_ADMIN_ALIAS, instanceCertDN, "RSA", 3650);
} catch (IllegalArgumentException e) {
throw new DomainException(_strMgr.getString("InvalidPassword"), e);
} catch (IOException e) {
throw new DomainException(_strMgr.getString("SomeProblemWithKeytool"), e);
}
if (!keyStore.exists()) {
throw new DomainException("KeyTool command failed to create the keystore with the following output: " + keyToolOutput);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ SomeProblemWithKeytool= Domain creation process involves a step that creates pri
A temporary JKS-keystore\n will be created.\
You should replace it with proper keystore before using it for SSL.\n Refer to documentation for details.\
Actual error is:\n
InvalidPassword=Invalid password, try again with a different password.
KeystoreShouldntExist=Keystore file {0} should not exist in the domain template. Please remove it - keys should be generated for every domain for security reasons
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,6 @@ public final class CreateDomainCommand extends CLICommand {
@Param(name = "domain_name", primary = true)
private String domainName;

public CreateDomainCommand() {
}

/**
* Add --adminport and --instanceport options with proper default values. (Can't set default values above because it
* conflicts with --portbase option processing.)
Expand Down Expand Up @@ -192,7 +189,7 @@ protected void validate() throws CommandException, CommandValidationException {
}
}

public void verifyPortBase() throws CommandValidationException {
private void verifyPortBase() throws CommandValidationException {
if (usePortBase()) {
final int portbase = convertPortStr(portBase);
setOptionsWithPortBase(portbase);
Expand Down Expand Up @@ -264,7 +261,6 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti
} else {
char[] pwdArr = getAdminPassword();
adminPassword = pwdArr != null ? new String(pwdArr) : null;
boolean haveAdminPwd = true;
}

if (saveMasterPassword) {
Expand All @@ -274,10 +270,13 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti
if (masterPassword == null) {
if (useMasterPassword) {
char[] mpArr = getMasterPassword();
masterPassword = mpArr == null ? null : new String(mpArr);
masterPassword = mpArr == null ? KEYSTORE_PASSWORD_DEFAULT : new String(mpArr);
} else {
masterPassword = KEYSTORE_PASSWORD_DEFAULT;
}
} else {
// Even if we don't save it, we still need it to create keystores
masterPassword = KEYSTORE_PASSWORD_DEFAULT;
}

try {
Expand All @@ -291,17 +290,28 @@ protected int executeCommand() throws CommandException, CommandValidationExcepti
}

// saving the login information happens inside this method
createTheDomain(domainDir, domainProperties);
createTheDomain();
return 0;
} catch (CommandException ce) {
logger.info(ce.getLocalizedMessage());
throw new CommandException(strings.get("CouldNotCreateDomain", domainName), ce);
} catch (Exception e) {
logger.fine(e.getLocalizedMessage());
logger.fine(() -> getLocalizedMessageWithCauses(e));
throw new CommandException(strings.get("CouldNotCreateDomain", domainName), e);
}
}

private static String getLocalizedMessageWithCauses(Exception e) {
StringBuilder message = new StringBuilder(e.getLocalizedMessage());
Throwable exceptionIterator = e;
while (exceptionIterator.getCause() != null) {
exceptionIterator = exceptionIterator.getCause();
message.append("\nCaused by:\n")
.append(exceptionIterator.getLocalizedMessage());
}
return message.toString();
}

/**
* Get the admin password as a required option.
*/
Expand Down Expand Up @@ -411,31 +421,32 @@ private void verifyPortBasePortIsValid(String portName, int portNum) throws Comm
* @param domainProperties properties to insert in domainConfig
* @throws CommandException if domain cannot be created
*/
private void createTheDomain(final String domainPath, Properties domainProperties) throws DomainException, CommandValidationException {
private void createTheDomain() throws DomainException, CommandValidationException {

if (FileUtils.safeGetCanonicalFile(new File(domainPath, domainName)).exists()) {
if (FileUtils.safeGetCanonicalFile(new File(domainDir, domainName)).exists()) {
throw new CommandValidationException(strings.get("DomainExists", domainName));
}
DomainConfig domainConfig = null;
if (template == null || template.endsWith(".jar")) {
domainConfig = new DomainConfig(domainName, domainPath, adminUser, adminPassword, masterPassword,
saveMasterPassword, adminPort, instancePort, domainProperties);
domainConfig.put(DomainConfig.K_VALIDATE_PORTS, Boolean.valueOf(checkPorts));
domainConfig.put(DomainConfig.KEYTOOLOPTIONS, keytoolOptions);
domainConfig.put(DomainConfig.K_TEMPLATE_NAME, template);
domainConfig.put(DomainConfig.K_PORTBASE, portBase);
domainConfig.put(DomainConfig.K_INITIAL_ADMIN_USER_GROUPS, Version.getDomainDefaultAdminGroups());
initSecureAdminSettings(domainConfig);
try {
DomainBuilder domainBuilder = new DomainBuilder(domainConfig);
domainBuilder.validateTemplate();
domainBuilder.run();
} catch (Exception e) {
throw new DomainException(e.getMessage());
}
} else {
if (template != null && !template.endsWith(".jar")) {
throw new DomainException(strings.get("InvalidTemplateValue", template));
}
domainConfig = new DomainConfig(domainName, domainDir, adminUser, adminPassword, masterPassword,
saveMasterPassword, adminPort, instancePort, domainProperties);
domainConfig.put(DomainConfig.K_VALIDATE_PORTS, Boolean.valueOf(checkPorts));
domainConfig.put(DomainConfig.KEYTOOLOPTIONS, keytoolOptions);
domainConfig.put(DomainConfig.K_TEMPLATE_NAME, template);
domainConfig.put(DomainConfig.K_PORTBASE, portBase);
domainConfig.put(DomainConfig.K_INITIAL_ADMIN_USER_GROUPS, Version.getDomainDefaultAdminGroups());
initSecureAdminSettings(domainConfig);
try {
DomainBuilder domainBuilder = new DomainBuilder(domainConfig);
domainBuilder.validateTemplate();
domainBuilder.run();
} catch (DomainException e) {
throw e;
} catch (Exception e) {
throw new DomainException("Failed to create domain " + domainName, e);
}
logger.info(strings.get("DomainCreated", domainName));
Integer aPort = (Integer) domainConfig.get(DomainConfig.K_ADMIN_PORT);
logger.info(strings.get("DomainPort", domainName, Integer.toString(aPort)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ UnknownException=Unknown exception while talking to server [{0}:{1}].\nPlease ma
###################
## delete-domain
DomainDeleted=Domain {0} deleted.
InvalidDomainPath=CLI138: Invalid domain path, {0}
CouldNotDeleteDomain=CLI139: Could not delete domain, {0}.
InvalidDomainPath=CLI138: Invalid domain path: {0}
CouldNotDeleteDomain=CLI139: Could not delete domain named {0}.
domain.fileinuse=A file or folder within domain {0} at {1} is in use. Stop using it before deleting the domain.
###################
## create-domain
InvalidCharInDomain=CLI129: Invalid character in domain name, {0}
CouldNotCreateDomain=CLI130: Could not create domain, {0}
InvalidCharInDomain=CLI129: Invalid character in domain name: {0}
CouldNotCreateDomain=CLI130: Could not create domain name {0}
RequireEitherOrOption=Option {0} or {1} must be specified.
AdminPassword=Enter the admin password
AdminPasswordAgain=Enter the admin password again
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@

import java.io.File;
import java.io.IOException;
import java.lang.System.Logger;

import org.glassfish.security.common.FileRealmHelper;

import static com.sun.enterprise.util.SystemPropertyConstants.KEYSTORE_FILENAME_DEFAULT;
import static com.sun.enterprise.util.SystemPropertyConstants.KEYSTORE_PASSWORD_DEFAULT;
import static com.sun.enterprise.util.SystemPropertyConstants.TRUSTSTORE_FILENAME_DEFAULT;
import static java.lang.System.Logger.Level.INFO;

public class DomainSecurity extends MasterPasswordFileManager {

private static final Logger LOG = System.getLogger(DomainSecurity.class.getName());

/**
* Modifies the contents of given keyfile with administrator's user-name and password. Uses the FileRealm classes that
Expand Down Expand Up @@ -75,7 +78,11 @@ void createPasswordAliasKeystore(File pwFile, String password) throws Repository
*/
void createSSLCertificateDatabase(File configDir, DomainConfig config, String masterPassword) throws RepositoryException {
createKeyStore(new File(configDir, KEYSTORE_FILENAME_DEFAULT), config, masterPassword);
changeKeystorePassword(KEYSTORE_PASSWORD_DEFAULT, masterPassword, new File(configDir, TRUSTSTORE_FILENAME_DEFAULT));
final File trustStoreFile = new File(configDir, TRUSTSTORE_FILENAME_DEFAULT);
if (trustStoreFile.exists()) {
changeKeystorePassword(KEYSTORE_PASSWORD_DEFAULT, masterPassword, trustStoreFile);
}
LOG.log(INFO, () -> "Copying keystore certificates to the trust store: " + trustStoreFile);
copyCertificatesToTrustStore(configDir, masterPassword);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,10 @@ public KeyStore loadKeyStore() throws IOException {
* @param dn distinguished name, e.g. "CN=localhost, OU=Development, O=Example, L=City, ST=State, C=Country"
* @param keyAlgorithm the key algorithm, e.g. "RSA", "DSA", "EC"
* @param certValidity the validity of the certificate in days, must be positive
* @return Output of the keytool command
* @throws IOException
*/
public void generateKeyPair(String alias, String dn, String keyAlgorithm, int certValidity) throws IOException {
public String generateKeyPair(String alias, String dn, String keyAlgorithm, int certValidity) throws IOException {
final List<String> command = List.of(
KEYTOOL,
"-J-Duser.language=en",
Expand All @@ -139,7 +140,7 @@ public void generateKeyPair(String alias, String dn, String keyAlgorithm, int ce
LOG.log(DEBUG, "Created directory for keystore: {0}", keyStore.getParentFile());
}
// 4 times - once for key store, once for key password, each once more for confirmation
execute(command, password, password, password, password);
return execute(command, password, password, password, password);
}


Expand Down Expand Up @@ -202,9 +203,10 @@ public void copyCertificate(String alias, File destKeyStoreFile, char[] destKeyS
*
* @param alias the alias of the certificate to export
* @param outputFile the file to write the certificate to. It must not exist yet.
* @return Output of the keytool command
* @throws IOException if an error occurs during the process
*/
public void exportCertificate(String alias, final File outputFile) throws IOException {
public String exportCertificate(String alias, final File outputFile) throws IOException {
final List<String> exportCommand = List.of(
KEYTOOL,
"-J-Duser.language=en",
Expand All @@ -214,7 +216,7 @@ public void exportCertificate(String alias, final File outputFile) throws IOExce
"-keystore", keyStore.getAbsolutePath(),
"-file", outputFile.getAbsolutePath()
);
execute(exportCommand, password);
return execute(exportCommand, password);
}


Expand All @@ -226,6 +228,8 @@ public void exportCertificate(String alias, final File outputFile) throws IOExce
* @throws IOException
*/
public void changeKeyStorePassword(char[] newPassword) throws IOException {
LOG.log(INFO, () -> "Changing password on the keystore file: " + keyStore);

// We grab the current key store, so everything is done in memory until the end.
final KeyStore ks = loadKeyStore();
final char[] oldPassword = password;
Expand Down Expand Up @@ -280,8 +284,8 @@ public void changeKeyPassword(String alias, char[] oldPassword, char[] newPasswo
}


private void execute(final List<String> command, char[]... stdinLines) throws IOException {
execute(keyStore, command, stdinLines);
private String execute(final List<String> command, char[]... stdinLines) throws IOException {
return execute(keyStore, command, stdinLines);
}


Expand Down Expand Up @@ -362,7 +366,7 @@ private static void changeKeyPassword(KeyStore keyStore, String alias, char[] ol
}


private static void execute(final File keyStore, final List<String> command, final char[]... stdinLines) throws IOException {
private static String execute(final File keyStore, final List<String> command, final char[]... stdinLines) throws IOException {
LOG.log(INFO, () -> "Executing command: " + command.stream().collect(Collectors.joining(" ")));
final ProcessBuilder builder = new ProcessBuilder(command).directory(keyStore.getParentFile());
final Process process;
Expand All @@ -387,6 +391,10 @@ private static void execute(final File keyStore, final List<String> command, fin
if (exitCode != 0) {
throw new IOException("KeyTool command failed with exit code: " + exitCode + " and output: " + output);
}
if (output.endsWith("Too many failures - try later\n")) {
throw new IllegalArgumentException("KeyTool command failed with exit code: " + exitCode + " and output: " + output);
}
return output;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Interrupted", e);
Expand Down
Loading