From ad4a854d04ccaa00ae6e4f2895c1be746d2fe5a0 Mon Sep 17 00:00:00 2001 From: petrberan Date: Thu, 9 Jun 2022 15:16:22 +0200 Subject: [PATCH] [ELY-2343] Add a web option to the Elytron Tool --- .../security/tool/CredentialStoreCommand.java | 34 +++++++++++ .../security/tool/ElytronToolMessages.java | 6 ++ .../tool/FileSystemEncryptRealmCommand.java | 61 +++++++++++++++---- .../security/tool/FileSystemRealmCommand.java | 35 +++++++++-- .../wildfly/security/tool/MaskCommand.java | 36 +++++++++-- .../wildfly/security/tool/VaultCommand.java | 34 +++++++++++ 6 files changed, 187 insertions(+), 19 deletions(-) diff --git a/tool/src/main/java/org/wildfly/security/tool/CredentialStoreCommand.java b/tool/src/main/java/org/wildfly/security/tool/CredentialStoreCommand.java index 3f6d765d73a..d159938b74a 100644 --- a/tool/src/main/java/org/wildfly/security/tool/CredentialStoreCommand.java +++ b/tool/src/main/java/org/wildfly/security/tool/CredentialStoreCommand.java @@ -17,10 +17,13 @@ */ package org.wildfly.security.tool; +import java.awt.Desktop; import java.io.IOException; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -104,6 +107,16 @@ class CredentialStoreCommand extends Command { public static final String CREDENTIAL_STORE_COMMAND = "credential-store"; + + private static final String DOCS_VERSION = "27"; + private static final String DOCS_URI = "https://docs.wildfly.org/" + DOCS_VERSION + "/WildFly_Elytron_Security.html"; + + public static final String STORE_LOCATION_PARAM = "location"; + public static final String IMPLEMENTATION_PROPERTIES_PARAM = "properties"; + public static final String CREDENTIAL_STORE_PASSWORD_PARAM = "password"; + public static final String CREDENTIAL_STORE_TYPE_PARAM = "type"; + public static final String SALT_PARAM = "salt"; + public static final String ITERATION_PARAM = "iteration"; public static final String PASSWORD_CREDENTIAL_VALUE_PARAM = "secret"; public static final String ADD_ALIAS_PARAM = "add"; public static final String CHECK_ALIAS_PARAM = "exists"; @@ -112,6 +125,7 @@ class CredentialStoreCommand extends Command { public static final String REMOVE_ALIAS_PARAM = "remove"; public static final String ENTRY_TYPE_PARAM = "entry-type"; public static final String SIZE_PARAM = "size"; + public static final String WEB_PARAM = "web"; public static final String GENERATE_KEY_PAIR_PARAM = "generate-key-pair"; public static final String ALGORITHM_PARAM = "algorithm"; @@ -176,6 +190,9 @@ class CredentialStoreCommand extends Command { options.addOption("k", ALGORITHM_PARAM, true, ElytronToolMessages.msg.cmdLineKeyAlgorithmDesc()); options.addOption("kp", KEY_PASSPHRASE_PARAM, true, ElytronToolMessages.msg.cmdLineKeyPassphraseDesc()); + opt = Option.builder().longOpt(WEB_PARAM).desc(ElytronToolMessages.msg.cmdWebDesc()).build(); + options.addOption(opt); + OptionGroup privateKP = new OptionGroup(); Option privateString = new Option("pvk", PRIVATE_KEY_STRING_PARAM, true, ElytronToolMessages.msg.cmdLinePrivateKeyStringDesc()); Option privateLocation = new Option("pvl", PRIVATE_KEY_LOCATION_PARAM, true, ElytronToolMessages.msg.cmdLinePrivateKeyLocationDesc()); @@ -347,6 +364,23 @@ public void execute(String[] args) throws Exception { setStatus(ElytronTool.ElytronToolExitStatus_OK); return; } + if (cmdLine.hasOption(WEB_PARAM)) { + if (Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)){ + try { + desktop.browse(new URI(DOCS_URI + "#CredentialStore")); + setStatus(ElytronTool.ElytronToolExitStatus_OK); + return; + } catch (IOException | URISyntaxException e) { + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } + } + } + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } printDuplicatesWarning(cmdLine); diff --git a/tool/src/main/java/org/wildfly/security/tool/ElytronToolMessages.java b/tool/src/main/java/org/wildfly/security/tool/ElytronToolMessages.java index 4b876d33b25..f33350a7ccf 100644 --- a/tool/src/main/java/org/wildfly/security/tool/ElytronToolMessages.java +++ b/tool/src/main/java/org/wildfly/security/tool/ElytronToolMessages.java @@ -744,6 +744,12 @@ public interface ElytronToolMessages extends BasicLogger { @Message(id = NONE, value = "A tool that assists with Elytron configuration") String cmdElytronToolDescription(); + @Message(id = NONE, value = "Open online documentation for the command (Action)") + String cmdWebDesc(); + + @Message(id = NONE, value = "Unable to open the browser.") + IOException unableToOpenBrowser(); + // Numeric Errors @Message(id = 35, value = "Only one of '%s' and '%s' can be specified at the same time") IllegalArgumentException mutuallyExclusiveOptions(String first, String second); diff --git a/tool/src/main/java/org/wildfly/security/tool/FileSystemEncryptRealmCommand.java b/tool/src/main/java/org/wildfly/security/tool/FileSystemEncryptRealmCommand.java index 844332d76de..b186793fbbb 100644 --- a/tool/src/main/java/org/wildfly/security/tool/FileSystemEncryptRealmCommand.java +++ b/tool/src/main/java/org/wildfly/security/tool/FileSystemEncryptRealmCommand.java @@ -17,49 +17,45 @@ */ package org.wildfly.security.tool; + import static org.wildfly.security.tool.Params.BULK_CONVERT_PARAM; -import static org.wildfly.security.tool.Params.CREATE_CREDENTIAL_STORE_PARAM; -import static org.wildfly.security.tool.Params.CREDENTIAL_STORE_LOCATION_PARAM; -import static org.wildfly.security.tool.Params.DEBUG_PARAM; import static org.wildfly.security.tool.Params.DEFAULT_KEY_PAIR_ALIAS; import static org.wildfly.security.tool.Params.DEFAULT_LEVELS; import static org.wildfly.security.tool.Params.DEFAULT_SECRET_KEY_ALIAS; import static org.wildfly.security.tool.Params.DIRECTORY_PARAM; -import static org.wildfly.security.tool.Params.ENCODED_PARAM; import static org.wildfly.security.tool.Params.FILE_PARAM; import static org.wildfly.security.tool.Params.HASH_CHARSET_PARAM; -import static org.wildfly.security.tool.Params.HASH_ENCODING_PARAM; -import static org.wildfly.security.tool.Params.HELP_PARAM; import static org.wildfly.security.tool.Params.INPUT_LOCATION_PARAM; import static org.wildfly.security.tool.Params.KEYSTORE_PARAM; import static org.wildfly.security.tool.Params.KEYSTORE_TYPE_PARAM; import static org.wildfly.security.tool.Params.KEY_PAIR_ALIAS_PARAM; -import static org.wildfly.security.tool.Params.LEVELS_PARAM; import static org.wildfly.security.tool.Params.LINE_SEPARATOR; import static org.wildfly.security.tool.Params.NAME_PARAM; import static org.wildfly.security.tool.Params.OUTPUT_LOCATION_PARAM; import static org.wildfly.security.tool.Params.PASSWORD_ENV_PARAM; import static org.wildfly.security.tool.Params.PASSWORD_PARAM; -import static org.wildfly.security.tool.Params.REALM_NAME_PARAM; -import static org.wildfly.security.tool.Params.SECRET_KEY_ALIAS_PARAM; -import static org.wildfly.security.tool.Params.SILENT_PARAM; import static org.wildfly.security.tool.Params.SUMMARY_DIVIDER; -import static org.wildfly.security.tool.Params.SUMMARY_PARAM; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; + +import java.awt.Desktop; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.security.KeyPair; +import java.security.Provider; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; import java.util.stream.Stream; import javax.crypto.SecretKey; import org.apache.commons.cli.CommandLine; @@ -72,6 +68,7 @@ import org.wildfly.security.auth.realm.FileSystemSecurityRealm; import org.wildfly.security.auth.realm.FileSystemSecurityRealmBuilder; import org.wildfly.security.password.spec.Encoding; +import org.wildfly.security.password.WildFlyElytronPasswordProvider; import org.wildfly.security.tool.help.DescriptionSection; import org.wildfly.security.tool.help.HelpCommand; import org.wildfly.security.tool.help.OptionsSection; @@ -89,9 +86,30 @@ class FileSystemEncryptRealmCommand extends Command { static final String FILE_SYSTEM_ENCRYPT_COMMAND = "filesystem-realm-encrypt"; + private static final String DOCS_VERSION = "27"; + private static final String DOCS_URI = "https://docs.wildfly.org/" + DOCS_VERSION + "/WildFly_Elytron_Security.html"; + + private static final String HELP_PARAM = "help"; + private static final String DEBUG_PARAM = "debug"; + private static final String SILENT_PARAM = "silent"; + private static final String SUMMARY_PARAM = "summary"; + private static final String INPUT_REALM_LOCATION_PARAM = "input-location"; + private static final String REALM_NAME_PARAM = "realm-name"; + private static final String OUTPUT_REALM_LOCATION_PARAM = "output-location"; + private static final String CREDENTIAL_STORE_LOCATION_PARAM = "credential-store"; + private static final String CREATE_CREDENTIAL_STORE_PARAM = "create"; + private static final String SECRET_KEY_ALIAS_PARAM = "secret-key"; + private static final String HASH_ENCODING_PARAM = "hash-encoding"; + private static final String ENCODED_PARAM = "encoded"; + private static final String LEVELS_PARAM = "levels"; private static final String POPULATE_SECRET_KEY_PARAM = "populate"; private static final String DEFAULT_FILESYSTEM_REALM_NAME = "encrypted-filesystem-realm"; + private static final String WEB_PARAM = "web"; + public static Supplier ELYTRON_PASSWORD_PROVIDERS = () -> new Provider[]{ + WildFlyElytronPasswordProvider.getInstance() + }; + private final List descriptors = new ArrayList<>(); private final List PARAMS_LIST = new ArrayList<>(Arrays.asList(INPUT_LOCATION_PARAM, OUTPUT_LOCATION_PARAM)); @@ -176,6 +194,9 @@ class FileSystemEncryptRealmCommand extends Command { option.setArgName(FILE_PARAM); options.addOption(option); + option = Option.builder().longOpt(WEB_PARAM).desc(ElytronToolMessages.msg.cmdWebDesc()).build(); + options.addOption(option); + option = Option.builder().longOpt(HELP_PARAM).desc(ElytronToolMessages.msg.cmdLineHelp()).build(); options.addOption(option); @@ -392,6 +413,24 @@ public void execute(String[] args) throws Exception { setStatus(ElytronTool.ElytronToolExitStatus_OK); return; } + if (cmdLine.hasOption(WEB_PARAM)) { + if (Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)){ + try { + desktop.browse(new URI(DOCS_URI + + "#converting-an-unencrypted-filesystem-realm-into-an-encrypted-filesystem-realm")); + setStatus(ElytronTool.ElytronToolExitStatus_OK); + return; + } catch (IOException | URISyntaxException e) { + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } + } + } + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } if (cmdLine.hasOption(SILENT_PARAM)) { silentMode = true; } diff --git a/tool/src/main/java/org/wildfly/security/tool/FileSystemRealmCommand.java b/tool/src/main/java/org/wildfly/security/tool/FileSystemRealmCommand.java index aff167ece0b..e823858a563 100644 --- a/tool/src/main/java/org/wildfly/security/tool/FileSystemRealmCommand.java +++ b/tool/src/main/java/org/wildfly/security/tool/FileSystemRealmCommand.java @@ -18,18 +18,17 @@ package org.wildfly.security.tool; import static org.wildfly.security.tool.Params.BULK_CONVERT_PARAM; -import static org.wildfly.security.tool.Params.DEBUG_PARAM; import static org.wildfly.security.tool.Params.DIRECTORY_PARAM; import static org.wildfly.security.tool.Params.FILE_PARAM; -import static org.wildfly.security.tool.Params.HELP_PARAM; import static org.wildfly.security.tool.Params.LINE_SEPARATOR; import static org.wildfly.security.tool.Params.NAME_PARAM; import static org.wildfly.security.tool.Params.OUTPUT_LOCATION_PARAM; -import static org.wildfly.security.tool.Params.SILENT_PARAM; import static org.wildfly.security.tool.Params.SUMMARY_DIVIDER; -import static org.wildfly.security.tool.Params.SUMMARY_PARAM; +import java.awt.Desktop; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -77,12 +76,20 @@ class FileSystemRealmCommand extends Command { static final String FILE_SYSTEM_REALM_COMMAND = "filesystem-realm"; + private static final String DOCS_VERSION = "27"; + private static final String DOCS_URI = "https://docs.wildfly.org/" + DOCS_VERSION + "/WildFly_Elytron_Security.html"; + + private static final String HELP_PARAM = "help"; + private static final String DEBUG_PARAM = "debug"; + private static final String SILENT_PARAM = "silent"; + private static final String SUMMARY_PARAM = "summary"; private static final String USERS_FILE_PARAM = "users-file"; private static final String ROLES_FILE_PARAM = "roles-file"; private static final String FILESYSTEM_REALM_NAME_PARAM = "filesystem-realm-name"; private static final String SECURITY_DOMAIN_NAME_PARAM = "security-domain-name"; private static final String DEFAULT_FILESYSTEM_REALM_NAME = "converted-properties-filesystem-realm"; private static final String DEFAULT_SECURITY_DOMAIN_NAME = "converted-properties-security-domain"; + private static final String WEB_PARAM = "web"; private List descriptors = new ArrayList<>(); private final List PARAMS_LIST = new ArrayList<>(Arrays.asList(USERS_FILE_PARAM, ROLES_FILE_PARAM, OUTPUT_LOCATION_PARAM, FILESYSTEM_REALM_NAME_PARAM, SECURITY_DOMAIN_NAME_PARAM)); @@ -123,6 +130,9 @@ class FileSystemRealmCommand extends Command { option.setArgName(NAME_PARAM); options.addOption(option); + option = Option.builder().longOpt(WEB_PARAM).desc(ElytronToolMessages.msg.cmdWebDesc()).build(); + options.addOption(option); + option = Option.builder().longOpt(HELP_PARAM).desc(ElytronToolMessages.msg.cmdLineHelp()).build(); options.addOption(option); @@ -224,6 +234,23 @@ public void execute(String[] args) throws Exception { setStatus(ElytronTool.ElytronToolExitStatus_OK); return; } + if (cmdLine.hasOption(WEB_PARAM)) { + if (Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)){ + try { + desktop.browse(new URI(DOCS_URI + "#Properties_File_Based_Authentication_Migration")); + setStatus(ElytronTool.ElytronToolExitStatus_OK); + return; + } catch (IOException | URISyntaxException e) { + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } + } + } + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } if (cmdLine.hasOption(SILENT_PARAM)) { silentMode = true; } diff --git a/tool/src/main/java/org/wildfly/security/tool/MaskCommand.java b/tool/src/main/java/org/wildfly/security/tool/MaskCommand.java index 154a95d9582..e79e6ec4203 100644 --- a/tool/src/main/java/org/wildfly/security/tool/MaskCommand.java +++ b/tool/src/main/java/org/wildfly/security/tool/MaskCommand.java @@ -17,6 +17,10 @@ */ package org.wildfly.security.tool; +import java.awt.Desktop; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.security.GeneralSecurityException; import java.security.SecureRandom; @@ -31,10 +35,6 @@ import org.wildfly.security.tool.help.UsageSection; import org.wildfly.security.util.PasswordBasedEncryptionUtil; -import static org.wildfly.security.tool.Params.DEBUG_PARAM; -import static org.wildfly.security.tool.Params.HELP_PARAM; -import static org.wildfly.security.tool.Params.ITERATION_PARAM; -import static org.wildfly.security.tool.Params.SALT_PARAM; import static org.wildfly.security.util.PasswordUtil.generateSecureRandomString; /** @@ -49,7 +49,16 @@ class MaskCommand extends Command { * Command string */ public static final String MASK_COMMAND = "mask"; + + private static final String DOCS_VERSION = "27"; + private static final String DOCS_URI = "https://docs.wildfly.org/" + DOCS_VERSION + "/"; + + static final String SALT_PARAM = "salt"; + static final String ITERATION_PARAM = "iteration"; static final String SECRET_PARAM = "secret"; + static final String HELP_PARAM = "help"; + static final String DEBUG_PARAM = "debug"; + static final String WEB_PARAM = "web"; private final int defaultIterationCount = 10000; @@ -63,6 +72,7 @@ class MaskCommand extends Command { Option h = new Option("h", HELP_PARAM, false, ElytronToolMessages.msg.cmdLineHelp()); Option x = new Option("x", SECRET_PARAM, true, ElytronToolMessages.msg.cmdMaskSecretDesc()); Option d = new Option("d", DEBUG_PARAM, false, ElytronToolMessages.msg.cmdLineDebug()); + Option web = Option.builder().longOpt(WEB_PARAM).desc(ElytronToolMessages.msg.cmdWebDesc()).build(); x.setArgName("to encrypt"); options = new Options(); options.addOption(x); @@ -70,6 +80,7 @@ class MaskCommand extends Command { options.addOption(salt); options.addOption(iteration); options.addOption(d); + options.addOption(web); } @Override @@ -86,6 +97,23 @@ public void execute(String[] args) throws Exception { setStatus(ElytronTool.ElytronToolExitStatus_OK); return; } + if (cmdLine.hasOption(WEB_PARAM)) { + if (Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)){ + try { + desktop.browse(new URI(DOCS_URI + "Migration_Guide.html#credential-store-creation")); + setStatus(ElytronTool.ElytronToolExitStatus_OK); + return; + } catch (IOException | URISyntaxException e) { + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } + } + } + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } printDuplicatesWarning(cmdLine); diff --git a/tool/src/main/java/org/wildfly/security/tool/VaultCommand.java b/tool/src/main/java/org/wildfly/security/tool/VaultCommand.java index 3637c9ba667..13c36c79321 100644 --- a/tool/src/main/java/org/wildfly/security/tool/VaultCommand.java +++ b/tool/src/main/java/org/wildfly/security/tool/VaultCommand.java @@ -34,11 +34,14 @@ import static org.wildfly.security.tool.Params.STORE_LOCATION_PARAM; import static org.wildfly.security.tool.Params.SUMMARY_PARAM; +import java.awt.Desktop; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; @@ -87,6 +90,11 @@ public class VaultCommand extends Command { public static final String VAULT_COMMAND = "vault"; + private static final String DOCS_VERSION = "27"; + private static final String DOCS_URI = "https://docs.wildfly.org/" + DOCS_VERSION + "/WildFly_Elytron_Security.html"; + + public static final String STORE_LOCATION_PARAM = "location"; + public static final String PRINT_SUMMARY_PARAM = "summary"; public static final String FAIL_IF_EXIST_PARAM = "fail-if-exist"; public static final String MASK_PREFIX = "MASK-"; @@ -94,6 +102,13 @@ public class VaultCommand extends Command { public static final String KEYSTORE_PASSWORD_PARAM = "keystore-password"; public static final String ENC_DIR_PARAM = "enc-dir"; + public static final String SALT_PARAM = "salt"; + public static final String ITERATION_PARAM = "iteration"; + public static final String ALIAS_PARAM = "alias"; + public static final String HELP_PARAM = "help"; + public static final String DEBUG_PARAM = "debug"; + public static final String WEB_PARAM = "web"; + private static final class Descriptor { String keyStoreURL; String vaultPassword; @@ -158,6 +173,8 @@ public VaultCommand() { options.addOption(h); options.addOption(d); + o = Option.builder().longOpt(WEB_PARAM).desc(ElytronToolMessages.msg.cmdWebDesc()).build(); + options.addOption(o); } @Override @@ -170,6 +187,23 @@ public void execute(String[] args) throws Exception { setStatus(ElytronTool.ElytronToolExitStatus_OK); return; } + if (cmdLine.hasOption(WEB_PARAM)) { + if (Desktop.isDesktopSupported()){ + Desktop desktop = Desktop.getDesktop(); + if (desktop.isSupported(Desktop.Action.BROWSE)){ + try { + desktop.browse(new URI(DOCS_URI + "#Migrating_Existing_Vaults")); + setStatus(ElytronTool.ElytronToolExitStatus_OK); + return; + } catch (IOException | URISyntaxException e) { + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } + } + } + setStatus(GENERAL_CONFIGURATION_ERROR); + throw ElytronToolMessages.msg.unableToOpenBrowser(); + } boolean printSummary = cmdLine.hasOption(SUMMARY_PARAM);