Skip to content

Commit ea35e2c

Browse files
authored
[MGPG-105] Stop propagating bad practices (#71)
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
1 parent 6081ad4 commit ea35e2c

File tree

30 files changed

+152
-191
lines changed

30 files changed

+152
-191
lines changed

pgp-keys-map.list

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,13 @@
1616
# under the License.
1717

1818
commons-io:commons-io = 0x2DB4F1EF0FA761ECC4EA935C86FDC7E2A11262CB
19-
javax.inject:javax.inject = noSig
2019
org.apiguardian:apiguardian-api = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
2120
org.junit.jupiter:junit-jupiter-api = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
2221
org.junit.jupiter:junit-jupiter-params = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
2322
org.junit.platform:junit-platform-commons = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
2423
org.opentest4j:opentest4j = 0xFF6E2C001948C5F2F38B0CC385911F425EC61B51
2524
org.apache.maven.resolver = 0x522CA055B326A636D833EF6A0551FD3684FCBBB7
2625
org.apache.maven.shared:maven-invoker = 0x84789D24DF77A32433CE1F079EB80E92EB2135B1
27-
org.codehaus.plexus:plexus-cipher = 0x6A814B1F869C2BBEAB7CB7271A2A1C94BDE89688
2826
org.codehaus.plexus:plexus-classworlds = 0xB91AB7D2121DC6B0A61AA182D7742D58455ECC7C
2927
org.codehaus.plexus:plexus-component-annotations = 0xFA77DCFEF2EE6EB2DEBEDD2C012579464D01C06A
3028
org.codehaus.plexus:plexus-utils = 0xF254B35617DC255D9344BCFA873A8E86B4372146
31-
org.codehaus.plexus:plexus-sec-dispatcher = 0x2BE13D052E9AA567D657D9791FD507154FB9BA39
32-
org.hamcrest:hamcrest = 0xE3A9F95079E84CE201F7CF60BEDE11EAF1164480
33-
org.hamcrest:hamcrest-core = 0xE3A9F95079E84CE201F7CF60BEDE11EAF1164480
34-
org.slf4j:slf4j-api = 0x475F3B8E59E6E63AA78067482C7B12F2A511E325

pom.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,6 @@ under the License.
120120
<artifactId>plexus-utils</artifactId>
121121
<version>3.5.1</version>
122122
</dependency>
123-
<dependency>
124-
<groupId>org.codehaus.plexus</groupId>
125-
<artifactId>plexus-sec-dispatcher</artifactId>
126-
<version>2.0</version>
127-
</dependency>
128123

129124
<dependency>
130125
<groupId>org.junit.jupiter</groupId>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/no-main-artifact/pom.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ under the License.
4646
<groupId>org.apache.maven.plugins</groupId>
4747
<artifactId>maven-gpg-plugin</artifactId>
4848
<version>@project.version@</version>
49-
<configuration>
50-
<passphrase>TEST</passphrase>
51-
</configuration>
5249
<executions>
5350
<execution>
5451
<id>sign-artifacts</id>

src/it/settings.xml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,4 @@ under the License.
2323
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2424
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
2525

26-
<servers>
27-
<server>
28-
<id>gpg.passphrase</id>
29-
<passphrase>TEST</passphrase>
30-
</server>
31-
</servers>
32-
3326
</settings>

src/it/sign-and-deploy-file-with-extras/invoker.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
# under the License.
1717

1818
invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
19+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/sign-and-deploy-file-with-extras/test.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,5 @@
1818
file = test.jar
1919
pomFile = test.pom
2020
url = file:target/repo
21-
gpg.passphrase = TEST
2221
sources = test-sources.jar
2322
javadoc = test-javadoc.jar

src/it/sign-and-deploy-file-with-pom/invoker.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
# under the License.
1717

1818
invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
19+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/sign-and-deploy-file-with-pom/test.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,3 @@
1818
file = test.jar
1919
pomFile = test.pom
2020
url = file:target/repo
21-
gpg.passphrase = TEST

src/it/sign-and-deploy-file-without-pom/invoker.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
# under the License.
1717

1818
invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
19+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/sign-and-deploy-file-without-pom/test.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,3 @@ artifactId = test
2121
version = 1.0
2222
packaging = jar
2323
url = file:target/repo
24-
gpg.passphrase = TEST

src/it/sign-and-deploy-files/invoker.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
# under the License.
1717

1818
invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
19+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/sign-and-deploy-files/test.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
file = test.jar
1919
pomFile = test.pom
2020
url = file:target/repo
21-
gpg.passphrase = TEST
2221
sources = test-sources.jar
2322
javadoc = test-javadoc.jar
2423
files = test.zip,test-src.tar.gz,test.tar.gz

src/it/sign-and-deploy-not-jar-packaging/invoker.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
# under the License.
1717

1818
invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sign-and-deploy-file
19+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/sign-and-deploy-not-jar-packaging/test.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,3 @@ version = 1.0
2222
packaging = javadoc
2323
url = file:target/repo
2424
generatePom = false
25-
gpg.passphrase = TEST
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/sign-release-with-excludes/pom.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ under the License.
4646
<groupId>org.apache.maven.plugins</groupId>
4747
<artifactId>maven-gpg-plugin</artifactId>
4848
<version>@project.version@</version>
49-
<configuration>
50-
<passphrase>TEST</passphrase>
51-
</configuration>
5249
<executions>
5350
<execution>
5451
<id>sign-artifacts</id>

src/it/sign-release-without-passphrase/pom.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ under the License.
4646
<groupId>org.apache.maven.plugins</groupId>
4747
<artifactId>maven-gpg-plugin</artifactId>
4848
<version>@project.version@</version>
49-
<configuration>
50-
<passphraseServerId>non-existent</passphraseServerId>
51-
</configuration>
5249
<executions>
5350
<execution>
5451
<id>sign-artifacts</id>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/it/sign-release/pom.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ under the License.
4646
<groupId>org.apache.maven.plugins</groupId>
4747
<artifactId>maven-gpg-plugin</artifactId>
4848
<version>@project.version@</version>
49-
<configuration>
50-
<passphrase>TEST</passphrase>
51-
</configuration>
5249
<executions>
5350
<execution>
5451
<id>sign-artifacts</id>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
invoker.environmentVariables.MAVEN_GPG_PASSPHRASE = TEST

src/main/java/org/apache/maven/plugins/gpg/AbstractGpgMojo.java

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,28 @@
1919
package org.apache.maven.plugins.gpg;
2020

2121
import java.io.File;
22-
import java.io.IOException;
2322
import java.util.List;
2423

24+
import org.apache.maven.execution.MavenSession;
2525
import org.apache.maven.plugin.AbstractMojo;
2626
import org.apache.maven.plugin.MojoExecutionException;
2727
import org.apache.maven.plugin.MojoFailureException;
2828
import org.apache.maven.plugins.annotations.Component;
2929
import org.apache.maven.plugins.annotations.Parameter;
30-
import org.apache.maven.project.MavenProject;
31-
import org.apache.maven.settings.Server;
32-
import org.apache.maven.settings.Settings;
33-
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
34-
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
3530

3631
/**
3732
* @author Benjamin Bentmann
3833
*/
3934
public abstract class AbstractGpgMojo extends AbstractMojo {
35+
public static final String DEFAULT_ENV_MAVEN_GPG_PASSPHRASE = "MAVEN_GPG_PASSPHRASE";
36+
37+
/**
38+
* The env variable name where the GnuPG passphrase is set. The default value is {@code MAVEN_GPG_PASSPHRASE}.
39+
*
40+
* @since 3.2.0
41+
*/
42+
@Parameter(property = "gpg.passphraseEnvName", defaultValue = DEFAULT_ENV_MAVEN_GPG_PASSPHRASE)
43+
private String passphraseEnvName;
4044

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

5764
/**
5865
* Server id to lookup the passphrase under Maven settings.
5966
* @since 1.6
60-
*/
61-
@Parameter(property = "gpg.passphraseServerId", defaultValue = "gpg.passphrase")
67+
*
68+
* @deprecated Do not use this configuration, plugin will fail if set.
69+
**/
70+
@Deprecated
71+
@Parameter(property = "gpg.passphraseServerId")
6272
private String passphraseServerId;
6373

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

145+
/**
146+
* Skip doing the gpg signing.
147+
*/
148+
@Parameter(property = "gpg.skip", defaultValue = "false")
149+
private boolean skip;
150+
135151
/**
136152
* Sets the arguments to be passed to gpg. Example:
137153
*
@@ -148,22 +164,31 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
148164
private List<String> gpgArguments;
149165

150166
/**
151-
* Current user system settings for use in Maven.
152-
*
153-
* @since 1.6
154-
*/
155-
@Parameter(defaultValue = "${settings}", readonly = true)
156-
private Settings settings;
157-
158-
/**
159-
* Maven Security Dispatcher
160-
*
161-
* @since 1.6
167+
* @since 3.0.0
162168
*/
163169
@Component
164-
private SecDispatcher securityDispatcher;
170+
protected MavenSession session;
171+
172+
@Override
173+
public final void execute() throws MojoExecutionException, MojoFailureException {
174+
if (skip) {
175+
// We're skipping the signing stuff
176+
return;
177+
}
178+
if ((passphrase != null && !passphrase.trim().isEmpty())
179+
|| (passphraseServerId != null && !passphraseServerId.trim().isEmpty())) {
180+
// Stop propagating worst practices: passphrase MUST NOT be in any file on disk
181+
throw new MojoFailureException(
182+
"Do not store passphrase in any file (disk or SCM repository), rely on GnuPG agent or provide passphrase in "
183+
+ passphraseEnvName + " environment variable.");
184+
}
165185

166-
AbstractGpgSigner newSigner(MavenProject project) throws MojoExecutionException, MojoFailureException {
186+
doExecute();
187+
}
188+
189+
protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;
190+
191+
protected AbstractGpgSigner newSigner() throws MojoExecutionException, MojoFailureException {
167192
AbstractGpgSigner signer = new GpgSigner(executable);
168193

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

180-
loadGpgPassphrase();
205+
String passphrase =
206+
(String) session.getRepositorySession().getConfigProperties().get("env." + passphraseEnvName);
207+
if (passphrase != null) {
208+
signer.setPassPhrase(passphrase);
209+
}
181210

182211
signer.setPassPhrase(passphrase);
183212
if (null == passphrase && !useAgent) {
184213
if (!interactive) {
185214
throw new MojoFailureException("Cannot obtain passphrase in batch mode");
186215
}
187-
try {
188-
signer.setPassPhrase(signer.getPassphrase(project));
189-
} catch (IOException e) {
190-
throw new MojoExecutionException("Exception reading passphrase", e);
191-
}
192216
}
193217

194218
return signer;
195219
}
196-
197-
/**
198-
* Load and decrypt gpg passphrase from Maven settings if not given from plugin configuration
199-
*
200-
* @throws MojoFailureException
201-
*/
202-
private void loadGpgPassphrase() throws MojoFailureException {
203-
if (this.passphrase == null || this.passphrase.isEmpty()) {
204-
Server server = this.settings.getServer(passphraseServerId);
205-
206-
if (server != null) {
207-
if (server.getPassphrase() != null) {
208-
try {
209-
this.passphrase = securityDispatcher.decrypt(server.getPassphrase());
210-
} catch (SecDispatcherException e) {
211-
throw new MojoFailureException("Unable to decrypt gpg passphrase", e);
212-
}
213-
}
214-
}
215-
}
216-
}
217220
}

0 commit comments

Comments
 (0)