From 034cbd72b7fff97a8160413caecea9a3d0788522 Mon Sep 17 00:00:00 2001 From: Or Geva Date: Thu, 28 Dec 2023 15:26:10 +0200 Subject: [PATCH] Encrypt build info properties file (#900) --- pom.xml | 4 +- .../gradle/ArtifactoryGradleConfigurator.java | 2 +- .../ivy/ArtifactoryIvyConfigurator.java | 2 +- .../ArtifactoryIvyFreeStyleConfigurator.java | 2 +- .../maven3/ArtifactoryMaven3Configurator.java | 2 +- .../extractor/MavenExtractorEnvironment.java | 2 +- .../common/executors/EnvExtractor.java | 8 +- .../common/executors/GradleExecutor.java | 2 +- .../common/executors/MavenExecutor.java | 2 +- .../executors/MavenGradleEnvExtractor.java | 4 +- .../org/jfrog/hudson/util/ExtractorUtils.java | 88 +++++++++++++------ 11 files changed, 78 insertions(+), 40 deletions(-) diff --git a/pom.xml b/pom.xml index 7512f8987..db9201ba1 100644 --- a/pom.xml +++ b/pom.xml @@ -41,8 +41,8 @@ true - 2.41.7 - 5.1.10 + 2.41.11 + 5.1.13 diff --git a/src/main/java/org/jfrog/hudson/gradle/ArtifactoryGradleConfigurator.java b/src/main/java/org/jfrog/hudson/gradle/ArtifactoryGradleConfigurator.java index 5878ce323..8a99ed51c 100644 --- a/src/main/java/org/jfrog/hudson/gradle/ArtifactoryGradleConfigurator.java +++ b/src/main/java/org/jfrog/hudson/gradle/ArtifactoryGradleConfigurator.java @@ -492,7 +492,7 @@ public void buildEnvVars(Map env) { try { ExtractorUtils.addBuilderInfoArguments(env, build, listener, - finalPublisherBuilder.build(), resolverContext, build.getWorkspace(), launcher); + finalPublisherBuilder.build(), resolverContext, build.getWorkspace(), launcher, useArtifactoryGradlePlugin); } catch (Exception e) { log.println(e.getMessage()); throw new RuntimeException(e); diff --git a/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyConfigurator.java b/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyConfigurator.java index ae0570042..b4d338126 100644 --- a/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyConfigurator.java +++ b/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyConfigurator.java @@ -303,7 +303,7 @@ public Environment setUp(final AbstractBuild build, final Launcher launcher, fin @Override public void buildEnvVars(Map env) { try { - ExtractorUtils.addBuilderInfoArguments(env, build, listener, context, null, build.getWorkspace(), launcher); + ExtractorUtils.addBuilderInfoArguments(env, build, listener, context, null, build.getWorkspace(), launcher, false); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyFreeStyleConfigurator.java b/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyFreeStyleConfigurator.java index 36c459f13..fa70fa622 100644 --- a/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyFreeStyleConfigurator.java +++ b/src/main/java/org/jfrog/hudson/ivy/ArtifactoryIvyFreeStyleConfigurator.java @@ -321,7 +321,7 @@ public void buildEnvVars(Map env) { try { String actualDependencyDirPath = actualDependencyDirPath(build, launcher); env.put("ARTIFACTORY_CACHE_LIBS", actualDependencyDirPath); - ExtractorUtils.addBuilderInfoArguments(env, build, listener, finalPublisherContext, null, build.getWorkspace(), launcher); + ExtractorUtils.addBuilderInfoArguments(env, build, listener, finalPublisherContext, null, build.getWorkspace(), launcher, false); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/jfrog/hudson/maven3/ArtifactoryMaven3Configurator.java b/src/main/java/org/jfrog/hudson/maven3/ArtifactoryMaven3Configurator.java index 43adffe5e..236199e99 100644 --- a/src/main/java/org/jfrog/hudson/maven3/ArtifactoryMaven3Configurator.java +++ b/src/main/java/org/jfrog/hudson/maven3/ArtifactoryMaven3Configurator.java @@ -402,7 +402,7 @@ public Environment setUp(final AbstractBuild build, final Launcher launcher, fin @Override public void buildEnvVars(Map env) { try { - ExtractorUtils.addBuilderInfoArguments(env, build, listener, publisherContext, resolverContext, build.getWorkspace(), launcher); + ExtractorUtils.addBuilderInfoArguments(env, build, listener, publisherContext, resolverContext, build.getWorkspace(), launcher, false); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/jfrog/hudson/maven3/extractor/MavenExtractorEnvironment.java b/src/main/java/org/jfrog/hudson/maven3/extractor/MavenExtractorEnvironment.java index efc992c7f..c7fd89138 100644 --- a/src/main/java/org/jfrog/hudson/maven3/extractor/MavenExtractorEnvironment.java +++ b/src/main/java/org/jfrog/hudson/maven3/extractor/MavenExtractorEnvironment.java @@ -138,7 +138,7 @@ public void buildEnvVars(Map env) { } ArtifactoryClientConfiguration configuration = ExtractorUtils.addBuilderInfoArguments( - env, build, buildListener, publisherContext, resolverContext, build.getWorkspace(), launcher); + env, build, buildListener, publisherContext, resolverContext, build.getWorkspace(), launcher, false); propertiesFilePath = configuration.getPropertiesFile(); } catch (Exception e) { throw new RuntimeException(e); diff --git a/src/main/java/org/jfrog/hudson/pipeline/common/executors/EnvExtractor.java b/src/main/java/org/jfrog/hudson/pipeline/common/executors/EnvExtractor.java index 58a3e8f0f..7e920015e 100644 --- a/src/main/java/org/jfrog/hudson/pipeline/common/executors/EnvExtractor.java +++ b/src/main/java/org/jfrog/hudson/pipeline/common/executors/EnvExtractor.java @@ -35,8 +35,13 @@ public abstract class EnvExtractor implements Executor { private Launcher launcher; private FilePath tempDir; private EnvVars env; + private final boolean skipEncryption; public EnvExtractor(Run build, BuildInfo buildInfo, Deployer publisher, Resolver resolver, TaskListener buildListener, Launcher launcher, FilePath tempDir, EnvVars env) { + this(build, buildInfo, publisher, resolver, buildListener, launcher, tempDir, env, false); + } + + public EnvExtractor(Run build, BuildInfo buildInfo, Deployer publisher, Resolver resolver, TaskListener buildListener, Launcher launcher, FilePath tempDir, EnvVars env, boolean skipEncryption) { this.build = build; this.buildInfo = buildInfo; this.buildListener = buildListener; @@ -45,6 +50,7 @@ public EnvExtractor(Run build, BuildInfo buildInfo, Deployer publisher, Resolver this.launcher = launcher; this.tempDir = tempDir; this.env = env; + this.skipEncryption = skipEncryption; } protected abstract void addExtraConfiguration(ArtifactoryClientConfiguration configuration); @@ -87,7 +93,7 @@ public ArtifactoryClientConfiguration createArtifactoryClientConfiguration() thr } public void persistConfiguration(ArtifactoryClientConfiguration configuration) throws IOException, InterruptedException { - ExtractorUtils.persistConfiguration(configuration, env, tempDir, launcher); + ExtractorUtils.persistConfiguration(configuration, env, tempDir, launcher, skipEncryption); String propertiesFilePath = configuration.getPropertiesFile(); env.put(BuildInfoConfigProperties.PROP_PROPS_FILE, propertiesFilePath); } diff --git a/src/main/java/org/jfrog/hudson/pipeline/common/executors/GradleExecutor.java b/src/main/java/org/jfrog/hudson/pipeline/common/executors/GradleExecutor.java index eb978288b..eee7dc9c7 100644 --- a/src/main/java/org/jfrog/hudson/pipeline/common/executors/GradleExecutor.java +++ b/src/main/java/org/jfrog/hudson/pipeline/common/executors/GradleExecutor.java @@ -69,7 +69,7 @@ public void execute() throws Exception { ExtractorUtils.addVcsDetailsToEnv(new FilePath(ws, rootDir), extendedEnv, listener); tempDir = ExtractorUtils.createAndGetTempDir(ws); EnvExtractor envExtractor = new MavenGradleEnvExtractor(build, - buildInfo, deployer, gradleBuild.getResolver(), listener, launcher, tempDir, extendedEnv); + buildInfo, deployer, gradleBuild.getResolver(), listener, launcher, tempDir, extendedEnv, gradleBuild.isUsesPlugin()); envExtractor.execute(); ArgumentListBuilder args = getGradleExecutor(); Utils.launch("Gradle", launcher, args, extendedEnv, listener, ws); diff --git a/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenExecutor.java b/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenExecutor.java index 0ac443a59..e4cfe9f00 100644 --- a/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenExecutor.java +++ b/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenExecutor.java @@ -55,7 +55,7 @@ public void execute() throws Exception { ExtractorUtils.addVcsDetailsToEnv(new FilePath(ws, pom), extendedEnv, listener); FilePath tempDir = ExtractorUtils.createAndGetTempDir(ws); EnvExtractor envExtractor = new MavenGradleEnvExtractor(build, - buildInfo, deployer, mavenBuild.getResolver(), listener, launcher, tempDir, extendedEnv); + buildInfo, deployer, mavenBuild.getResolver(), listener, launcher, tempDir, extendedEnv, false); envExtractor.execute(); String stepOpts = mavenBuild.getOpts(); String mavenOpts = stepOpts + ( diff --git a/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenGradleEnvExtractor.java b/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenGradleEnvExtractor.java index 77940b8a4..c0185d123 100644 --- a/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenGradleEnvExtractor.java +++ b/src/main/java/org/jfrog/hudson/pipeline/common/executors/MavenGradleEnvExtractor.java @@ -15,8 +15,8 @@ */ public class MavenGradleEnvExtractor extends EnvExtractor { - public MavenGradleEnvExtractor(Run build, BuildInfo buildInfo, Deployer publisher, Resolver resolver, TaskListener buildListener, Launcher launcher, FilePath tempDir, EnvVars env) { - super(build, buildInfo, publisher, resolver, buildListener, launcher, tempDir, env); + public MavenGradleEnvExtractor(Run build, BuildInfo buildInfo, Deployer publisher, Resolver resolver, TaskListener buildListener, Launcher launcher, FilePath tempDir, EnvVars env, boolean skipEncryption) { + super(build, buildInfo, publisher, resolver, buildListener, launcher, tempDir, env, skipEncryption); } @Override diff --git a/src/main/java/org/jfrog/hudson/util/ExtractorUtils.java b/src/main/java/org/jfrog/hudson/util/ExtractorUtils.java index f71f92b12..02c6c37de 100644 --- a/src/main/java/org/jfrog/hudson/util/ExtractorUtils.java +++ b/src/main/java/org/jfrog/hudson/util/ExtractorUtils.java @@ -22,7 +22,10 @@ import hudson.EnvVars; import hudson.FilePath; import hudson.Util; -import hudson.model.*; +import hudson.model.AbstractBuild; +import hudson.model.Computer; +import hudson.model.Run; +import hudson.model.TaskListener; import hudson.slaves.SlaveComputer; import hudson.util.IOUtils; import jenkins.model.Jenkins; @@ -37,6 +40,7 @@ import org.jfrog.build.extractor.clientConfiguration.ArtifactoryClientConfiguration; import org.jfrog.build.extractor.clientConfiguration.ClientProperties; import org.jfrog.build.extractor.clientConfiguration.IncludeExcludePatterns; +import org.jfrog.build.extractor.clientConfiguration.util.encryption.EncryptionKeyPair; import org.jfrog.build.extractor.clientConfiguration.util.spec.SpecsHelper; import org.jfrog.hudson.ArtifactoryServer; import org.jfrog.hudson.CredentialsConfig; @@ -52,8 +56,26 @@ import org.jfrog.hudson.util.publisher.PublisherContext; import javax.annotation.Nullable; -import java.io.*; -import java.util.*; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.file.Files; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; /** * @author Tomer Cohen @@ -201,7 +223,7 @@ private static String publicGitUrl(String gitUrl) { * @param resolverContext A context for resolver settings */ public static ArtifactoryClientConfiguration addBuilderInfoArguments(Map env, Run build, TaskListener listener, - PublisherContext publisherContext, ResolverContext resolverContext, FilePath ws, hudson.Launcher launcher) + PublisherContext publisherContext, ResolverContext resolverContext, FilePath ws, hudson.Launcher launcher, boolean skipEncryption) throws Exception { ArtifactoryClientConfiguration configuration = getArtifactoryClientConfiguration(env, build, null, listener, publisherContext, resolverContext); @@ -212,7 +234,7 @@ public static ArtifactoryClientConfiguration addBuilderInfoArguments(Map env, FilePath ws, - hudson.Launcher launcher) throws IOException, InterruptedException { + hudson.Launcher launcher, boolean skipEncryption) throws IOException, InterruptedException { + FilePath propertiesFile = createPropertiesFile(ws); + setPersistConfigurationEnv(configuration, propertiesFile, env); + savePropertiesToFile(configuration, propertiesFile, env, launcher, skipEncryption); + } + + private static FilePath createPropertiesFile(FilePath ws) throws IOException, InterruptedException { FilePath propertiesFile = ws.createTextTempFile("buildInfo", ".properties", ""); ActionableHelper.deleteFilePathOnExit(propertiesFile); + return propertiesFile; + } + + private static void setPersistConfigurationEnv(ArtifactoryClientConfiguration configuration, FilePath propertiesFile, + Map env) { configuration.setPropertiesFile(propertiesFile.getRemote()); env.put("BUILDINFO_PROPFILE", propertiesFile.getRemote()); env.put(BuildInfoConfigProperties.PROP_PROPS_FILE, propertiesFile.getRemote()); - // Jenkins prefixes env variables with 'env' but we need it clean.. + // Jenkins prefixes env variables with 'env' but we need it clean. System.setProperty(BuildInfoConfigProperties.PROP_PROPS_FILE, propertiesFile.getRemote()); - if (!(getComputer(launcher) instanceof SlaveComputer)) { - configuration.persistToPropertiesFile(); - } else { - try { - Properties properties = new Properties(); - properties.putAll(configuration.getAllRootConfig()); - properties.putAll(configuration.getAllProperties()); - // Properties that have the 'artifactory.' prefix are deprecated. - // For backward compatibility reasons, both will be added to the props map. - // The build-info 2.32.3 is the last version to be using the deprecated properties as its primary. - for (String key : properties.stringPropertyNames()) { - properties.put("artifactory." + key, properties.getProperty(key)); - } - OutputStream os = propertiesFile.write(); - try { - properties.store(os, ""); - } finally { - IOUtils.closeQuietly(os); - } - } catch (Exception e) { - throw new RuntimeException(e); + } + + private static void savePropertiesToFile(ArtifactoryClientConfiguration configuration, FilePath propertiesFile, + Map env, hudson.Launcher launcher, boolean skipEncryption) { + try (OutputStream outputStream = isSlaveEnvironment(launcher) ? + Files.newOutputStream(new File(configuration.getPropertiesFile()).getCanonicalFile().toPath()) : + propertiesFile.write()) { + if (skipEncryption) { + configuration.persistToPropertiesFile(); + } else { + EncryptionKeyPair keyPair = configuration.persistToEncryptedPropertiesFile(outputStream); + env.put(BuildInfoConfigProperties.PROP_PROPS_FILE_KEY, keyPair.getStringSecretKey()); + env.put(BuildInfoConfigProperties.PROP_PROPS_FILE_KEY_IV, keyPair.getStringIv()); } + } catch (IOException | InterruptedException | InvalidAlgorithmParameterException | NoSuchPaddingException | + IllegalBlockSizeException | NoSuchAlgorithmException | BadPaddingException | InvalidKeyException e) { + throw new RuntimeException(e); } } + private static boolean isSlaveEnvironment(hudson.Launcher launcher) { + return (getComputer(launcher) instanceof SlaveComputer); + } + private static Computer getComputer(hudson.Launcher launcher) { Computer computer = Computer.currentComputer(); if (computer != null) {