Skip to content

Commit e4dc062

Browse files
authored
[MGPG-79] fix handling of external pinentry programs in case the passphrase is not given (#9)
* [MGPG-79] fix handling of external pinentry programs in case the passphrase is not given.
1 parent 5902b2b commit e4dc062

File tree

11 files changed

+622
-8
lines changed

11 files changed

+622
-8
lines changed

pom.xml

+49
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ under the License.
6565
<mavenVersion>3.0</mavenVersion>
6666
<javaVersion>7</javaVersion>
6767
<project.build.outputTimestamp>2020-04-12T12:45:04Z</project.build.outputTimestamp>
68+
<resource.delimiter>@</resource.delimiter>
6869
</properties>
6970

7071
<dependencies>
@@ -145,9 +146,33 @@ under the License.
145146
<version>2.2</version>
146147
<scope>test</scope>
147148
</dependency>
149+
<dependency>
150+
<groupId>org.apache.maven.shared</groupId>
151+
<artifactId>maven-invoker</artifactId>
152+
<version>3.1.0</version>
153+
<scope>test</scope>
154+
</dependency>
148155
</dependencies>
149156

150157
<build>
158+
<testResources>
159+
<testResource>
160+
<directory>${basedir}/src/test/resources</directory>
161+
<filtering>true</filtering>
162+
<includes>
163+
<include>**/pom.xml</include>
164+
<include>**/settings.xml</include>
165+
</includes>
166+
</testResource>
167+
<testResource>
168+
<directory>${basedir}/src/test/resources</directory>
169+
<excludes>
170+
<exclude>**/pom.xml</exclude>
171+
<exclude>**/settings.xml</exclude>
172+
</excludes>
173+
</testResource>
174+
</testResources>
175+
151176
<pluginManagement>
152177
<plugins>
153178
<plugin>
@@ -205,6 +230,30 @@ under the License.
205230
<id>run-its</id>
206231
<build>
207232
<plugins>
233+
<plugin>
234+
<groupId>org.apache.maven.plugins</groupId>
235+
<artifactId>maven-failsafe-plugin</artifactId>
236+
<executions>
237+
<execution>
238+
<goals>
239+
<goal>integration-test</goal>
240+
<goal>verify</goal>
241+
</goals>
242+
</execution>
243+
</executions>
244+
<configuration>
245+
<environmentVariables>
246+
<JENKINS_MAVEN_AGENT_DISABLED>true</JENKINS_MAVEN_AGENT_DISABLED>
247+
</environmentVariables>
248+
<systemPropertyVariables>
249+
<maven.home>${maven.home}</maven.home>
250+
<https.protocols>${https.protocols}</https.protocols>
251+
<gpg.homedir>${project.build.testOutputDirectory}/gnupg</gpg.homedir>
252+
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
253+
<settingsFile>/it/settings.xml</settingsFile>
254+
</systemPropertyVariables>
255+
</configuration>
256+
</plugin>
208257
<plugin>
209258
<groupId>org.apache.maven.plugins</groupId>
210259
<artifactId>maven-invoker-plugin</artifactId>
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.buildResult = failure
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!--
4+
Licensed to the Apache Software Foundation (ASF) under one
5+
or more contributor license agreements. See the NOTICE file
6+
distributed with this work for additional information
7+
regarding copyright ownership. The ASF licenses this file
8+
to you under the Apache License, Version 2.0 (the
9+
"License"); you may not use this file except in compliance
10+
with the License. You may obtain a copy of the License at
11+
12+
http://www.apache.org/licenses/LICENSE-2.0
13+
14+
Unless required by applicable law or agreed to in writing,
15+
software distributed under the License is distributed on an
16+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
KIND, either express or implied. See the License for the
18+
specific language governing permissions and limitations
19+
under the License.
20+
-->
21+
22+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
<modelVersion>4.0.0</modelVersion>
24+
25+
<groupId>org.apache.maven.its.gpg.srwop</groupId>
26+
<artifactId>test</artifactId>
27+
<version>1.0</version>
28+
<packaging>jar</packaging>
29+
30+
<description>
31+
Tests that signing with a missing passphrase in Maven batch mode (non-interactive mode) does not hang.
32+
</description>
33+
34+
<properties>
35+
<maven.test.skip>true</maven.test.skip>
36+
</properties>
37+
38+
<build>
39+
<plugins>
40+
<plugin>
41+
<groupId>org.apache.maven.plugins</groupId>
42+
<artifactId>maven-compiler-plugin</artifactId>
43+
<version>2.0.2</version>
44+
</plugin>
45+
<plugin>
46+
<groupId>org.apache.maven.plugins</groupId>
47+
<artifactId>maven-gpg-plugin</artifactId>
48+
<version>@project.version@</version>
49+
<configuration>
50+
<passphraseServerId>non-existent</passphraseServerId>
51+
</configuration>
52+
<executions>
53+
<execution>
54+
<id>sign-artifacts</id>
55+
<goals>
56+
<goal>sign</goal>
57+
</goals>
58+
</execution>
59+
</executions>
60+
</plugin>
61+
<plugin>
62+
<groupId>org.apache.maven.plugins</groupId>
63+
<artifactId>maven-install-plugin</artifactId>
64+
<version>2.2</version>
65+
<configuration>
66+
<updateReleaseInfo>true</updateReleaseInfo>
67+
</configuration>
68+
</plugin>
69+
<plugin>
70+
<groupId>org.apache.maven.plugins</groupId>
71+
<artifactId>maven-jar-plugin</artifactId>
72+
<version>2.1</version>
73+
</plugin>
74+
<plugin>
75+
<groupId>org.apache.maven.plugins</groupId>
76+
<artifactId>maven-resources-plugin</artifactId>
77+
<version>2.2</version>
78+
</plugin>
79+
<plugin>
80+
<groupId>org.apache.maven.plugins</groupId>
81+
<artifactId>maven-source-plugin</artifactId>
82+
<version>2.0.4</version>
83+
<executions>
84+
<execution>
85+
<id>attach-sources</id>
86+
<goals>
87+
<goal>jar</goal>
88+
</goals>
89+
</execution>
90+
</executions>
91+
</plugin>
92+
<plugin>
93+
<groupId>org.apache.maven.plugins</groupId>
94+
<artifactId>maven-surefire-plugin</artifactId>
95+
<version>2.3.1</version>
96+
</plugin>
97+
</plugins>
98+
</build>
99+
100+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
/*
3+
* Licensed to the Apache Software Foundation (ASF) under one
4+
* or more contributor license agreements. See the NOTICE file
5+
* distributed with this work for additional information
6+
* regarding copyright ownership. The ASF licenses this file
7+
* to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance
9+
* with the License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing,
14+
* software distributed under the License is distributed on an
15+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
* KIND, either express or implied. See the License for the
17+
* specific language governing permissions and limitations
18+
* under the License.
19+
*/
20+
21+
import java.io.*;
22+
import org.codehaus.plexus.util.FileUtils;
23+
24+
File buildLog = new File( basedir, "build.log" );
25+
String logContent = FileUtils.fileRead(buildLog);
26+
27+
// assert that the Maven build properly failed and did not time out
28+
if ( !logContent.contains( "Total time: " ) || !logContent.contains( "Finished at: " ) )
29+
{
30+
throw new Exception( "Maven build did not fail, but timed out" );
31+
}
32+
33+
// assert that the Maven build failed, because pinentry is not allowed in non-interactive mode
34+
if ( !logContent.contains( "[GNUPG:] FAILURE sign 67108949" ) )
35+
{
36+
throw new Exception( "Maven build did not fail in consequence of pinentry not being available to GPG" );
37+
}
38+

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

+28-8
Original file line numberDiff line numberDiff line change
@@ -97,20 +97,25 @@ protected void generateSignatureForFile( File file, File signature )
9797
cmd.createArg().setValue( "--no-use-agent" );
9898
}
9999
}
100-
else
101-
{
102-
cmd.createArg().setValue( "--pinentry-mode" );
103-
cmd.createArg().setValue( "loopback" );
104-
}
105100

106101
InputStream in = null;
107102
if ( null != passphrase )
108103
{
109-
// make --passphrase-fd effective in gpg2
110-
cmd.createArg().setValue( "--batch" );
104+
if ( gpgVersion.isAtLeast( GpgVersion.parse( "2.0" ) ) )
105+
{
106+
// required for option --passphrase-fd since GPG 2.0
107+
cmd.createArg().setValue( "--batch" );
108+
}
111109

112-
cmd.createArg().setValue( "--passphrase-fd" );
110+
if ( gpgVersion.isAtLeast( GpgVersion.parse( "2.1" ) ) )
111+
{
112+
// required for option --passphrase-fd since GPG 2.1
113+
cmd.createArg().setValue( "--pinentry-mode" );
114+
cmd.createArg().setValue( "loopback" );
115+
}
113116

117+
// make --passphrase-fd effective in gpg2
118+
cmd.createArg().setValue( "--passphrase-fd" );
114119
cmd.createArg().setValue( "0" );
115120

116121
// Prepare the input stream which will be used to pass the passphrase to the executable
@@ -128,9 +133,24 @@ protected void generateSignatureForFile( File file, File signature )
128133

129134
cmd.createArg().setValue( "--detach-sign" );
130135

136+
if ( getLog().isDebugEnabled() )
137+
{
138+
// instruct GPG to write status information to stdout
139+
cmd.createArg().setValue( "--status-fd" );
140+
cmd.createArg().setValue( "1" );
141+
}
142+
131143
if ( !isInteractive )
132144
{
145+
cmd.createArg().setValue( "--batch" );
133146
cmd.createArg().setValue( "--no-tty" );
147+
148+
if ( null == passphrase && gpgVersion.isAtLeast( GpgVersion.parse( "2.1" ) ) )
149+
{
150+
// prevent GPG from spawning input prompts in Maven non-interactive mode
151+
cmd.createArg().setValue( "--pinentry-mode" );
152+
cmd.createArg().setValue( "error" );
153+
}
134154
}
135155

136156
if ( !defaultKeyring )
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.apache.maven.plugins.gpg.it;
2+
3+
/*
4+
* Licensed to the Apache Software Foundation (ASF) under one
5+
* or more contributor license agreements. See the NOTICE file
6+
* distributed with this work for additional information
7+
* regarding copyright ownership. The ASF licenses this file
8+
* to you under the Apache License, Version 2.0 (the
9+
* "License"); you may not use this file except in compliance
10+
* with the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing,
15+
* software distributed under the License is distributed on an
16+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
* KIND, either express or implied. See the License for the
18+
* specific language governing permissions and limitations
19+
* under the License.
20+
*/
21+
22+
import java.io.File;
23+
24+
import org.apache.maven.shared.invoker.InvocationResult;
25+
26+
public class BuildResult
27+
{
28+
29+
private final File buildLog;
30+
private final InvocationResult invocationResult;
31+
32+
public BuildResult( final File buildLog, final InvocationResult invocationResult )
33+
{
34+
this.buildLog = buildLog;
35+
this.invocationResult = invocationResult;
36+
}
37+
38+
public File getBuildLog()
39+
{
40+
return buildLog;
41+
}
42+
43+
public InvocationResult getInvocationResult()
44+
{
45+
return invocationResult;
46+
}
47+
48+
}

0 commit comments

Comments
 (0)