Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MGPG-136] Windows passphrase corruption #120

Merged
merged 7 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/main/java/org/apache/maven/plugins/gpg/AbstractGpgMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,26 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
@Parameter(property = "gpg.bestPractices", defaultValue = "false")
private boolean bestPractices;

/**
* Whether to append the passphrase with LF character or not, as on some systems and some GPG executable combinations
cstamas marked this conversation as resolved.
Show resolved Hide resolved
* lack of this character may cause some issues. Since 3.2.0 this character was appended, but as
* {@link System#lineSeparator()} which in turn causes issues in binary handling of stdin (as I assume GPG does),
* since on windows this is {@code "\r\n"} (while on Unix-relatives is only {@code "\n"}, and GPG handles only
* {@code "\n"}. This may lead to "corruption" of passphrase with one extra {@code "\r"} character. This parameter
* affects ONLY the GPG signer, not the BC signer.
* <p>
* By default, this parameter is {@code null} and plugin will behave as pre-3.2.7 versions. If this parameter is
* explicitly set to {@code true}, it will append passphrase with {@code "\n"} character ONLY (as opposed to pre-3.2.7
* behaviour where it used {@link System#lineSeparator()} and used {@code "\r\n"}. If this parameter is
* explicitly set to {@code false}, the passphrase is used as-is, nothing is appended.
*
* @since 3.2.7
* @see <a href="https://issues.apache.org/jira/browse/MGPG-99">MGPG-99</a>
* @see <a href="https://issues.apache.org/jira/browse/MGPG-136">MGPG-136</a>
*/
@Parameter(property = "gpg.passphraseLf")
private Boolean passphraseLf;

/**
* Current user system settings for use in Maven.
*
Expand Down Expand Up @@ -345,6 +365,7 @@ protected AbstractGpgSigner newSigner(MavenProject mavenProject) throws MojoFail
signer.setPublicKeyring(publicKeyring);
signer.setLockMode(lockMode);
signer.setArgs(gpgArguments);
signer.setPassphraseLf(passphraseLf);

// "new way": env prevails
String passphrase =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public abstract class AbstractGpgSigner {

protected String passphrase;

protected Boolean passphraseLf;

private File outputDir;

private File buildDir;
Expand Down Expand Up @@ -98,6 +100,10 @@ public void setPassPhrase(String s) {
passphrase = s;
}

public void setPassphraseLf(Boolean b) {
this.passphraseLf = b;
}

public void setOutputDirectory(File out) {
outputDir = out;
}
Expand Down
17 changes: 13 additions & 4 deletions src/main/java/org/apache/maven/plugins/gpg/GpgSigner.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,20 @@ protected void generateSignatureForFile(File file, File signature) throws MojoEx
cmd.createArg().setValue("--passphrase-fd");
cmd.createArg().setValue("0");

// Prepare the input stream which will be used to pass the passphrase to the executable
if (!passphrase.endsWith(System.lineSeparator())) {
in = new ByteArrayInputStream((passphrase + System.lineSeparator()).getBytes());
// obey passphraseLf
if (passphraseLf != null) {
if (passphraseLf) {
in = new ByteArrayInputStream((passphrase + '\n').getBytes());
} else {
in = new ByteArrayInputStream((passphrase).getBytes());
}
} else {
in = new ByteArrayInputStream(passphrase.getBytes());
// Prepare the input stream which will be used to pass the passphrase to the executable
if (!passphrase.endsWith(System.lineSeparator())) {
in = new ByteArrayInputStream((passphrase + System.lineSeparator()).getBytes());
} else {
in = new ByteArrayInputStream(passphrase.getBytes());
}
}
}

Expand Down