Skip to content

Commit

Permalink
Encrypt build info properties file (#900)
Browse files Browse the repository at this point in the history
  • Loading branch information
Or-Geva authored Dec 28, 2023
1 parent d9e5fde commit 034cbd7
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 40 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
<!--Skip integration tests unless explicitly requested with -DskipITs=false-->
<skipITs>true</skipITs>

<buildinfo.version>2.41.7</buildinfo.version>
<buildinfo.gradle.version>5.1.10</buildinfo.gradle.version>
<buildinfo.version>2.41.11</buildinfo.version>
<buildinfo.gradle.version>5.1.13</buildinfo.gradle.version>
</properties>

<repositories>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ public void buildEnvVars(Map<String, String> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ public Environment setUp(final AbstractBuild build, final Launcher launcher, fin
@Override
public void buildEnvVars(Map<String, String> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ public void buildEnvVars(Map<String, String> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ public Environment setUp(final AbstractBuild build, final Launcher launcher, fin
@Override
public void buildEnvVars(Map<String, String> 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void buildEnvVars(Map<String, String> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 + (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
88 changes: 60 additions & 28 deletions src/main/java/org/jfrog/hudson/util/ExtractorUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -201,7 +223,7 @@ private static String publicGitUrl(String gitUrl) {
* @param resolverContext A context for resolver settings
*/
public static ArtifactoryClientConfiguration addBuilderInfoArguments(Map<String, String> 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);
Expand All @@ -212,7 +234,7 @@ public static ArtifactoryClientConfiguration addBuilderInfoArguments(Map<String,
// Create tempdir for properties file
FilePath tempDir = createAndGetTempDir(ws);

persistConfiguration(configuration, env, tempDir, launcher);
persistConfiguration(configuration, env, tempDir, launcher, skipEncryption);
return configuration;
}

Expand Down Expand Up @@ -549,39 +571,49 @@ public static void addBuildRootIfNeeded(AbstractBuild build, ArtifactoryClientCo
}

public static void persistConfiguration(ArtifactoryClientConfiguration configuration, Map<String, String> 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<String, String> 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<String, String> 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) {
Expand Down

0 comments on commit 034cbd7

Please sign in to comment.