Skip to content

Commit

Permalink
[MGPG-105] Stop propagating bad practices (#71)
Browse files Browse the repository at this point in the history
Storing any kind of "secret" on disk is bad.

This change makes passphrase possible to come in two ways:
* if interactive, via gpg-agent (as before)
* if non-interactive, via Env variable

Plugin from now on FAILS, if there is any kind of "secret" attempted to be configured in any other way that those two above.

---

https://issues.apache.org/jira/browse/MGPG-105
  • Loading branch information
cstamas committed Mar 3, 2024
1 parent 6081ad4 commit ea35e2c
Show file tree
Hide file tree
Showing 30 changed files with 152 additions and 191 deletions.
6 changes: 0 additions & 6 deletions pgp-keys-map.list
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,13 @@
# under the License.

commons-io:commons-io = 0x2DB4F1EF0FA761ECC4EA935C86FDC7E2A11262CB
javax.inject:javax.inject = noSig
org.apiguardian:apiguardian-api = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
org.junit.jupiter:junit-jupiter-api = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
org.junit.jupiter:junit-jupiter-params = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
org.junit.platform:junit-platform-commons = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
org.opentest4j:opentest4j = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
org.apache.maven.resolver = 0x522CA055B326A636D833EF6A0551FD3684FCBBB7
org.apache.maven.shared:maven-invoker = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
org.codehaus.plexus:plexus-cipher = 0x6A814B1F869C2BBEAB7CB7271A2A1C94BDE89688
org.codehaus.plexus:plexus-classworlds = 0xB91AB7D2121DC6B0A61AA182D7742D58455ECC7C
org.codehaus.plexus:plexus-component-annotations = 0xFA77DCFEF2EE6EB2DEBEDD2C012579464D01C06A
org.codehaus.plexus:plexus-utils = 0xF254B35617DC255D9344BCFA873A8E86B4372146
org.codehaus.plexus:plexus-sec-dispatcher = 0x2BE13D052E9AA567D657D9791FD507154FB9BA39
org.hamcrest:hamcrest = 0xE3A9F95079E84CE201F7CF60BEDE11EAF1164480
org.hamcrest:hamcrest-core = 0xE3A9F95079E84CE201F7CF60BEDE11EAF1164480
org.slf4j:slf4j-api = 0x475F3B8E59E6E63AA78067482C7B12F2A511E325
5 changes: 0 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,6 @@ under the License.
<artifactId>plexus-utils</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-sec-dispatcher</artifactId>
<version>2.0</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
18 changes: 18 additions & 0 deletions src/it/no-main-artifact/invoker.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
3 changes: 0 additions & 3 deletions src/it/no-main-artifact/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ under the License.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<passphrase>TEST</passphrase>
</configuration>
<executions>
<execution>
<id>sign-artifacts</id>
Expand Down
7 changes: 0 additions & 7 deletions src/it/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,4 @@ under the License.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

<servers>
<server>
<id>gpg.passphrase</id>
<passphrase>TEST</passphrase>
</server>
</servers>

</settings>
1 change: 1 addition & 0 deletions src/it/sign-and-deploy-file-with-extras/invoker.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
# under the License.

invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
1 change: 0 additions & 1 deletion src/it/sign-and-deploy-file-with-extras/test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,5 @@
file = test.jar
pomFile = test.pom
url = file:target/repo
gpg.passphrase = TEST
sources = test-sources.jar
javadoc = test-javadoc.jar
1 change: 1 addition & 0 deletions src/it/sign-and-deploy-file-with-pom/invoker.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
# under the License.

invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
1 change: 0 additions & 1 deletion src/it/sign-and-deploy-file-with-pom/test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@
file = test.jar
pomFile = test.pom
url = file:target/repo
gpg.passphrase = TEST
1 change: 1 addition & 0 deletions src/it/sign-and-deploy-file-without-pom/invoker.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
# under the License.

invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
1 change: 0 additions & 1 deletion src/it/sign-and-deploy-file-without-pom/test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ artifactId = test
version = 1.0
packaging = jar
url = file:target/repo
gpg.passphrase = TEST
1 change: 1 addition & 0 deletions src/it/sign-and-deploy-files/invoker.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
# under the License.

invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
1 change: 0 additions & 1 deletion src/it/sign-and-deploy-files/test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
file = test.jar
pomFile = test.pom
url = file:target/repo
gpg.passphrase = TEST
sources = test-sources.jar
javadoc = test-javadoc.jar
files = test.zip,test-src.tar.gz,test.tar.gz
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
# under the License.

invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
1 change: 0 additions & 1 deletion src/it/sign-and-deploy-not-jar-packaging/test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,3 @@ version = 1.0
packaging = javadoc
url = file:target/repo
generatePom = false
gpg.passphrase = TEST
18 changes: 18 additions & 0 deletions src/it/sign-release-with-excludes/invoker.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
3 changes: 0 additions & 3 deletions src/it/sign-release-with-excludes/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ under the License.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<passphrase>TEST</passphrase>
</configuration>
<executions>
<execution>
<id>sign-artifacts</id>
Expand Down
3 changes: 0 additions & 3 deletions src/it/sign-release-without-passphrase/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ under the License.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<passphraseServerId>non-existent</passphraseServerId>
</configuration>
<executions>
<execution>
<id>sign-artifacts</id>
Expand Down
18 changes: 18 additions & 0 deletions src/it/sign-release/invoker.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
3 changes: 0 additions & 3 deletions src/it/sign-release/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ under the License.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<passphrase>TEST</passphrase>
</configuration>
<executions>
<execution>
<id>sign-artifacts</id>
Expand Down
18 changes: 18 additions & 0 deletions src/it/sign-with-passphase-from-maven-settings/invoker.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST
99 changes: 51 additions & 48 deletions src/main/java/org/apache/maven/plugins/gpg/AbstractGpgMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,28 @@
package org.apache.maven.plugins.gpg;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;

/**
* @author Benjamin Bentmann
*/
public abstract class AbstractGpgMojo extends AbstractMojo {
public static final String DEFAULT_ENV_MAVEN_GPG_PASSPHRASE = "MAVEN_GPG_PASSPHRASE";

/**
* The env variable name where the GnuPG passphrase is set. The default value is {@code MAVEN_GPG_PASSPHRASE}.
*
* @since 3.2.0
*/
@Parameter(property = "gpg.passphraseEnvName", defaultValue = DEFAULT_ENV_MAVEN_GPG_PASSPHRASE)
private String passphraseEnvName;

/**
* The directory from which gpg will load keyrings. If not specified, gpg will use the value configured for its
Expand All @@ -50,15 +54,21 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
/**
* The passphrase to use when signing. If not given, look up the value under Maven
* settings using server id at 'passphraseServerKey' configuration.
*
* @deprecated Do not use this configuration, plugin will fail if set.
**/
@Deprecated
@Parameter(property = "gpg.passphrase")
private String passphrase;

/**
* Server id to lookup the passphrase under Maven settings.
* @since 1.6
*/
@Parameter(property = "gpg.passphraseServerId", defaultValue = "gpg.passphrase")
*
* @deprecated Do not use this configuration, plugin will fail if set.
**/
@Deprecated
@Parameter(property = "gpg.passphraseServerId")
private String passphraseServerId;

/**
Expand Down Expand Up @@ -132,6 +142,12 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
@Parameter(property = "gpg.lockMode")
private String lockMode;

/**
* Skip doing the gpg signing.
*/
@Parameter(property = "gpg.skip", defaultValue = "false")
private boolean skip;

/**
* Sets the arguments to be passed to gpg. Example:
*
Expand All @@ -148,22 +164,31 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
private List<String> gpgArguments;

/**
* Current user system settings for use in Maven.
*
* @since 1.6
*/
@Parameter(defaultValue = "${settings}", readonly = true)
private Settings settings;

/**
* Maven Security Dispatcher
*
* @since 1.6
* @since 3.0.0
*/
@Component
private SecDispatcher securityDispatcher;
protected MavenSession session;

@Override
public final void execute() throws MojoExecutionException, MojoFailureException {
if (skip) {
// We're skipping the signing stuff
return;
}
if ((passphrase != null && !passphrase.trim().isEmpty())
|| (passphraseServerId != null && !passphraseServerId.trim().isEmpty())) {
// Stop propagating worst practices: passphrase MUST NOT be in any file on disk
throw new MojoFailureException(
"Do not store passphrase in any file (disk or SCM repository), rely on GnuPG agent or provide passphrase in "
+ passphraseEnvName + " environment variable.");
}

AbstractGpgSigner newSigner(MavenProject project) throws MojoExecutionException, MojoFailureException {
doExecute();
}

protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;

protected AbstractGpgSigner newSigner() throws MojoExecutionException, MojoFailureException {
AbstractGpgSigner signer = new GpgSigner(executable);

signer.setLog(getLog());
Expand All @@ -177,41 +202,19 @@ AbstractGpgSigner newSigner(MavenProject project) throws MojoExecutionException,
signer.setLockMode(lockMode);
signer.setArgs(gpgArguments);

loadGpgPassphrase();
String passphrase =
(String) session.getRepositorySession().getConfigProperties().get("env." + passphraseEnvName);
if (passphrase != null) {
signer.setPassPhrase(passphrase);
}

signer.setPassPhrase(passphrase);
if (null == passphrase && !useAgent) {
if (!interactive) {
throw new MojoFailureException("Cannot obtain passphrase in batch mode");
}
try {
signer.setPassPhrase(signer.getPassphrase(project));
} catch (IOException e) {
throw new MojoExecutionException("Exception reading passphrase", e);
}
}

return signer;
}

/**
* Load and decrypt gpg passphrase from Maven settings if not given from plugin configuration
*
* @throws MojoFailureException
*/
private void loadGpgPassphrase() throws MojoFailureException {
if (this.passphrase == null || this.passphrase.isEmpty()) {
Server server = this.settings.getServer(passphraseServerId);

if (server != null) {
if (server.getPassphrase() != null) {
try {
this.passphrase = securityDispatcher.decrypt(server.getPassphrase());
} catch (SecDispatcherException e) {
throw new MojoFailureException("Unable to decrypt gpg passphrase", e);
}
}
}
}
}
}
Loading

0 comments on commit ea35e2c

Please sign in to comment.