diff --git a/maven-wrapper-distribution/pom.xml b/maven-wrapper-distribution/pom.xml index 43df1a90..a124e5e8 100644 --- a/maven-wrapper-distribution/pom.xml +++ b/maven-wrapper-distribution/pom.xml @@ -23,7 +23,7 @@ under the License. org.apache.maven.wrapper maven-wrapper-parent - 3.3.5-SNAPSHOT + 3.4.0-SNAPSHOT maven-wrapper-distribution diff --git a/maven-wrapper-distribution/src/resources/mvnw b/maven-wrapper-distribution/src/resources/mvnw index 6deb5c2b..85f4507e 100755 --- a/maven-wrapper-distribution/src/resources/mvnw +++ b/maven-wrapper-distribution/src/resources/mvnw @@ -310,6 +310,38 @@ if [ -n "$wrapperSha256Sum" ]; then fi fi +# If specified, validate the SHA-512 sum of the Maven wrapper jar file +wrapperSha512Sum="" +while IFS="=" read -r key value; do + case "$key" in wrapperSha512Sum) + wrapperSha512Sum=$(trim "${value-}") + break + ;; + esac +done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha512Sum" ]; then + wrapperSha512Result=false + if command -v sha512sum >/dev/null; then + if echo "$wrapperSha512Sum $wrapperJarPath" | sha512sum -c - >/dev/null 2>&1; then + wrapperSha512Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$wrapperSha512Sum $wrapperJarPath" | shasum -a 512 -c >/dev/null 2>&1; then + wrapperSha512Result=true + fi + else + echo "Checksum validation was requested but neither 'sha512sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'wrapperSha512Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $wrapperSha512Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-512, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha512Sum property." >&2 + exit 1 + fi +fi + MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # For Cygwin, switch paths to Windows format before running java diff --git a/maven-wrapper-distribution/src/resources/mvnw.cmd b/maven-wrapper-distribution/src/resources/mvnw.cmd index 708460f9..1ad03ac5 100644 --- a/maven-wrapper-distribution/src/resources/mvnw.cmd +++ b/maven-wrapper-distribution/src/resources/mvnw.cmd @@ -172,6 +172,25 @@ IF NOT %WRAPPER_SHA_256_SUM%=="" ( if ERRORLEVEL 1 goto error ) +@REM If specified, validate the SHA-512 sum of the Maven wrapper jar file +SET WRAPPER_SHA_512_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha512Sum" SET WRAPPER_SHA_512_SUM=%%B +) +IF NOT %WRAPPER_SHA_512_SUM%=="" ( + powershell -Command "&{"^ + "Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA512).Hash.ToLower();"^ + "If('%WRAPPER_SHA_512_SUM%' -ne $hash){"^ + " Write-Error 'Error: Failed to validate Maven wrapper SHA-512, your Maven wrapper might be compromised.';"^ + " Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha512Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + @REM Provide a "standardized" way to retrieve the CLI args that will @REM work with both Windows and non-Windows executions. set MAVEN_CMD_LINE_ARGS=%* diff --git a/maven-wrapper-distribution/src/resources/only-mvnw b/maven-wrapper-distribution/src/resources/only-mvnw index 93373137..88471feb 100755 --- a/maven-wrapper-distribution/src/resources/only-mvnw +++ b/maven-wrapper-distribution/src/resources/only-mvnw @@ -108,11 +108,12 @@ trim() { scriptDir="$(dirname "$0")" scriptName="$(basename "$0")" -# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +# parse distributionUrl and optional distributionSha256Sum or distributionSha512Sum, requires .mvn/wrapper/maven-wrapper.properties while IFS="=" read -r key value; do case "${key-}" in distributionUrl) distributionUrl=$(trim "${value-}") ;; distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + distributionSha512Sum) distributionSha512Sum=$(trim "${value-}") ;; esac done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" @@ -249,6 +250,33 @@ if [ -n "${distributionSha256Sum-}" ]; then fi fi +# If specified, validate the SHA-512 sum of the Maven distribution zip file +if [ -n "${distributionSha512Sum-}" ]; then + distributionSha512Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha512Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha512sum >/dev/null; then + if echo "$distributionSha512Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha512sum -c - >/dev/null 2>&1; then + distributionSha512Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha512Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 512 -c >/dev/null 2>&1; then + distributionSha512Result=true + fi + else + echo "Checksum validation was requested but neither 'sha512sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha512Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha512Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-512, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha512Sum property." >&2 + exit 1 + fi +fi + # unzip and move if command -v unzip >/dev/null; then unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" diff --git a/maven-wrapper-distribution/src/resources/only-mvnw.cmd b/maven-wrapper-distribution/src/resources/only-mvnw.cmd index fc99db2f..e53321d7 100644 --- a/maven-wrapper-distribution/src/resources/only-mvnw.cmd +++ b/maven-wrapper-distribution/src/resources/only-mvnw.cmd @@ -146,6 +146,18 @@ if ($distributionSha256Sum) { } } +# If specified, validate the SHA-512 sum of the Maven distribution zip file +$distributionSha512Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha512Sum +if ($distributionSha512Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha512Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA512).Hash.ToLower() -ne $distributionSha512Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-512, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha512Sum property." + } +} + # unzip and move Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null diff --git a/maven-wrapper-plugin/pom.xml b/maven-wrapper-plugin/pom.xml index baea971e..dae36254 100644 --- a/maven-wrapper-plugin/pom.xml +++ b/maven-wrapper-plugin/pom.xml @@ -23,7 +23,7 @@ under the License. org.apache.maven.wrapper maven-wrapper-parent - 3.3.5-SNAPSHOT + 3.4.0-SNAPSHOT org.apache.maven.plugins diff --git a/maven-wrapper-plugin/src/it/projects/sha512_distribution/pom.xml b/maven-wrapper-plugin/src/it/projects/sha512_distribution/pom.xml new file mode 100644 index 00000000..b8e83ddc --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_distribution/pom.xml @@ -0,0 +1,69 @@ + + + + + + 4.0.0 + + org.apache.maven.plugins.it.wrapper + extension + 1.0.0-SNAPSHOT + pom + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + @version.exec-maven-plugin@ + + mvnw${cmd} + + 1 + + + -v + + + true + + + + + + + + + + windows + + windows + + + .cmd + + + + diff --git a/maven-wrapper-plugin/src/it/projects/sha512_distribution/test.properties b/maven-wrapper-plugin/src/it/projects/sha512_distribution/test.properties new file mode 100644 index 00000000..c4e5afcb --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_distribution/test.properties @@ -0,0 +1,20 @@ +# 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. + +alwaysUnpack=true +type=bin +distributionSha512Sum=256cdc53261371d6f6fefd92e99d85df5295d1f83ab826106768094a34e6f1b0eb4f7c30e75ada80218ed5bb384bdce334a6697354eef561f50adfc2113c881d \ No newline at end of file diff --git a/maven-wrapper-plugin/src/it/projects/sha512_distribution/verify.groovy b/maven-wrapper-plugin/src/it/projects/sha512_distribution/verify.groovy new file mode 100644 index 00000000..27bcdf84 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_distribution/verify.groovy @@ -0,0 +1,35 @@ + +/* + * 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. + */ + +assert new File(basedir,'mvnw').exists() +assert new File(basedir,'mvnw.cmd').exists() +assert !(new File(basedir,'mvnwDebug').exists()) +assert !(new File(basedir,'mvnwDebug.cmd').exists()) + +properties = new File(basedir,'.mvn/wrapper/maven-wrapper.properties') +assert properties.exists() +assert properties.text.contains('distributionSha512Sum=256cdc53261371d6f6fefd92e99d85df5295d1f83ab826106768094a34e6f1b0eb4f7c30e75ada80218ed5bb384bdce334a6697354eef561f50adfc2113c881d') + +log = new File(basedir, 'build.log').text +// check "mvn wrapper:wrapper" output +assert log.contains('Failed to validate Maven distribution SHA-512, your Maven distribution might be compromised.') + +// check "mvnw -v" output +assert log.contains('Apache Maven ') diff --git a/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/pom.xml b/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/pom.xml new file mode 100644 index 00000000..ccd5664a --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/pom.xml @@ -0,0 +1,71 @@ + + + + + + 4.0.0 + + org.apache.maven.plugins.it.wrapper + extension + 1.0.0-SNAPSHOT + pom + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + @version.exec-maven-plugin@ + + mvnw${cmd} + + 1 + + + -v + + + true + ${project.build.directory} + ${project.build.directory} + + + + + + + + + + windows + + windows + + + .cmd + + + + diff --git a/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/test.properties b/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/test.properties new file mode 100644 index 00000000..466cbfc8 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/test.properties @@ -0,0 +1,19 @@ +# 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. + +type=only-script +distributionSha512Sum=256cdc53261371d6f6fefd92e99d85df5295d1f83ab826106768094a34e6f1b0eb4f7c30e75ada80218ed5bb384bdce334a6697354eef561f50adfc2113c881d \ No newline at end of file diff --git a/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/verify.groovy b/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/verify.groovy new file mode 100644 index 00000000..d21329a8 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_type_only-script/verify.groovy @@ -0,0 +1,36 @@ + +/* + * 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. + */ + +assert new File(basedir,'mvnw').exists() +assert new File(basedir,'mvnw.cmd').exists() +assert !(new File(basedir,'mvnwDebug').exists()) +assert !(new File(basedir,'mvnwDebug.cmd').exists()) + +properties = new File(basedir,'.mvn/wrapper/maven-wrapper.properties') +assert properties.exists() +assert properties.text.contains('distributionSha512Sum=256cdc53261371d6f6fefd92e99d85df5295d1f83ab826106768094a34e6f1b0eb4f7c30e75ada80218ed5bb384bdce334a6697354eef561f50adfc2113c881d') + +log = new File(basedir, 'build.log').text +// check "mvn wrapper:wrapper" output +assert log.contains('Error: Failed to validate Maven distribution SHA-512, your Maven distribution might be compromised.') +assert !log.contains('shasum:') + +// check "mvnw -v" output +assert !log.contains('Apache Maven ') diff --git a/maven-wrapper-plugin/src/it/projects/sha512_wrapper/pom.xml b/maven-wrapper-plugin/src/it/projects/sha512_wrapper/pom.xml new file mode 100644 index 00000000..b8e83ddc --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_wrapper/pom.xml @@ -0,0 +1,69 @@ + + + + + + 4.0.0 + + org.apache.maven.plugins.it.wrapper + extension + 1.0.0-SNAPSHOT + pom + + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + @version.exec-maven-plugin@ + + mvnw${cmd} + + 1 + + + -v + + + true + + + + + + + + + + windows + + windows + + + .cmd + + + + diff --git a/maven-wrapper-plugin/src/it/projects/sha512_wrapper/test.properties b/maven-wrapper-plugin/src/it/projects/sha512_wrapper/test.properties new file mode 100644 index 00000000..c1f2c705 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_wrapper/test.properties @@ -0,0 +1,19 @@ +# 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. + +type=bin +wrapperSha512Sum=256cdc53261371d6f6fefd92e99d85df5295d1f83ab826106768094a34e6f1b0eb4f7c30e75ada80218ed5bb384bdce334a6697354eef561f50adfc2113c881d \ No newline at end of file diff --git a/maven-wrapper-plugin/src/it/projects/sha512_wrapper/verify.groovy b/maven-wrapper-plugin/src/it/projects/sha512_wrapper/verify.groovy new file mode 100644 index 00000000..919a8b28 --- /dev/null +++ b/maven-wrapper-plugin/src/it/projects/sha512_wrapper/verify.groovy @@ -0,0 +1,36 @@ + +/* + * 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. + */ + +assert new File(basedir,'mvnw').exists() +assert new File(basedir,'mvnw.cmd').exists() +assert !(new File(basedir,'mvnwDebug').exists()) +assert !(new File(basedir,'mvnwDebug.cmd').exists()) + +properties = new File(basedir,'.mvn/wrapper/maven-wrapper.properties') +assert properties.exists() +assert properties.text.contains('wrapperSha512Sum=256cdc53261371d6f6fefd92e99d85df5295d1f83ab826106768094a34e6f1b0eb4f7c30e75ada80218ed5bb384bdce334a6697354eef561f50adfc2113c881d') + +log = new File(basedir, 'build.log').text +// check "mvn wrapper:wrapper" output +assert log.contains('Error: Failed to validate Maven wrapper SHA-512, your Maven wrapper might be compromised.') +assert !log.contains('shasum:') + +// check "mvnw -v" output +assert !log.contains('Apache Maven ') diff --git a/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java b/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java index 6146ff88..e0ec554b 100644 --- a/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java +++ b/maven-wrapper-plugin/src/main/java/org/apache/maven/plugins/wrapper/WrapperMojo.java @@ -123,7 +123,14 @@ public class WrapperMojo extends AbstractMojo { */ @Parameter(property = "wrapperSha256Sum") private String wrapperSha256Sum; - + /** + * The expected SHA-512 checksum of the maven-wrapper.jar that is + * used to load the configured Maven distribution. + * + * @since 3.4.0 + */ + @Parameter(property = "wrapperSha512Sum") + private String wrapperSha512Sum; /** * The expected SHA-256 checksum of the Maven distribution that is * executed by the installed wrapper. @@ -132,7 +139,14 @@ public class WrapperMojo extends AbstractMojo { */ @Parameter(property = "distributionSha256Sum") private String distributionSha256Sum; - + /** + * The expected SHA-512 checksum of the Maven distribution that is + * executed by the installed wrapper. + * + * @since 3.4.0 + */ + @Parameter(property = "distributionSha512Sum") + private String distributionSha512Sum; /** * Determines if the Maven distribution should be downloaded * on every execution of the Maven wrapper. @@ -286,7 +300,7 @@ private void unpack(Artifact artifact, Path targetFolder) { unarchiver.setSourceFile(artifact.getFile()); if (!includeDebugScript) { unarchiver.setFileSelectors( - new FileSelector[] {fileInfo -> !fileInfo.getName().contains("Debug")}); + new FileSelector[]{fileInfo -> !fileInfo.getName().contains("Debug")}); } unarchiver.extract(); getLog().info("Unpacked " + buffer().strong(distributionType) + " type wrapper distribution " + artifact); @@ -332,12 +346,18 @@ private void replaceProperties(String wrapperVersion, Path targetFolder) throws if (distributionSha256Sum != null) { out.append("distributionSha256Sum=" + distributionSha256Sum + System.lineSeparator()); } + if (distributionSha512Sum != null) { + out.append("distributionSha512Sum=" + distributionSha512Sum + System.lineSeparator()); + } if (!distributionType.equals(TYPE_ONLY_SCRIPT)) { out.append("wrapperUrl=" + wrapperUrl + System.lineSeparator()); } if (wrapperSha256Sum != null) { out.append("wrapperSha256Sum=" + wrapperSha256Sum + System.lineSeparator()); } + if (wrapperSha512Sum != null) { + out.append("wrapperSha512Sum=" + wrapperSha512Sum + System.lineSeparator()); + } if (alwaysDownload) { out.append("alwaysDownload=" + Boolean.TRUE + System.lineSeparator()); } diff --git a/maven-wrapper/pom.xml b/maven-wrapper/pom.xml index 1a6c9224..75385120 100644 --- a/maven-wrapper/pom.xml +++ b/maven-wrapper/pom.xml @@ -23,7 +23,7 @@ under the License. org.apache.maven.wrapper maven-wrapper-parent - 3.3.5-SNAPSHOT + 3.4.0-SNAPSHOT maven-wrapper diff --git a/maven-wrapper/src/main/java/org/apache/maven/wrapper/Installer.java b/maven-wrapper/src/main/java/org/apache/maven/wrapper/Installer.java index 177bb429..39e54857 100644 --- a/maven-wrapper/src/main/java/org/apache/maven/wrapper/Installer.java +++ b/maven-wrapper/src/main/java/org/apache/maven/wrapper/Installer.java @@ -67,6 +67,8 @@ public Path createDist(WrapperConfiguration configuration) throws Exception { boolean alwaysUnpack = configuration.isAlwaysUnpack(); boolean verifyDistributionSha256Sum = !configuration.getDistributionSha256Sum().isEmpty(); + boolean verifyDistributionSha512Sum = + !configuration.getDistributionSha512Sum().isEmpty(); PathAssembler.LocalDistribution localDistribution = pathAssembler.getDistribution(configuration); Path localZipFile = localDistribution.getZipFile(); @@ -97,6 +99,13 @@ public Path createDist(WrapperConfiguration configuration) throws Exception { Verifier.SHA_256_ALGORITHM, configuration.getDistributionSha256Sum()); } + if (verifyDistributionSha512Sum) { + verifier.verify( + localZipFile, + "distributionSha512Sum", + Verifier.SHA_512_ALGORITHM, + configuration.getDistributionSha512Sum()); + } for (Path dir : dirs) { Logger.info("Deleting directory " + dir.toAbsolutePath()); deleteDir(dir); diff --git a/maven-wrapper/src/main/java/org/apache/maven/wrapper/Verifier.java b/maven-wrapper/src/main/java/org/apache/maven/wrapper/Verifier.java index 623f57a3..067cebea 100644 --- a/maven-wrapper/src/main/java/org/apache/maven/wrapper/Verifier.java +++ b/maven-wrapper/src/main/java/org/apache/maven/wrapper/Verifier.java @@ -29,5 +29,7 @@ public interface Verifier { String SHA_256_ALGORITHM = "SHA-256"; + String SHA_512_ALGORITHM = "SHA-512"; + void verify(Path file, String property, String algorithm, String expectedSum) throws Exception; } diff --git a/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperConfiguration.java b/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperConfiguration.java index c42bad9d..b1b9ed3d 100644 --- a/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperConfiguration.java +++ b/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperConfiguration.java @@ -45,6 +45,8 @@ public class WrapperConfiguration { private String distributionSha256Sum; + private String distributionSha512Sum; + public boolean isAlwaysDownload() { return alwaysDownload; } @@ -105,7 +107,15 @@ public String getDistributionSha256Sum() { return distributionSha256Sum; } + public String getDistributionSha512Sum() { + return distributionSha512Sum; + } + public void setDistributionSha256Sum(String distributionSha256Sum) { this.distributionSha256Sum = distributionSha256Sum; } + + public void setDistributionSha512Sum(String distributionSha512Sum) { + this.distributionSha512Sum = distributionSha512Sum; + } } diff --git a/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperExecutor.java b/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperExecutor.java index 5b7ace9f..14a53763 100644 --- a/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperExecutor.java +++ b/maven-wrapper/src/main/java/org/apache/maven/wrapper/WrapperExecutor.java @@ -49,6 +49,8 @@ public class WrapperExecutor { public static final String DISTRIBUTION_SHA_256_SUM = "distributionSha256Sum"; + public static final String DISTRIBUTION_SHA_512_SUM = "distributionSha512Sum"; + public static final String ALWAYS_DOWNLOAD = "alwaysDownload"; public static final String ALWAYS_UNPACK = "alwaysUnpack"; @@ -85,6 +87,7 @@ public static WrapperExecutor forWrapperPropertiesFile(Path propertiesFile) { config.setZipPath(Paths.get( getProperty(ZIP_STORE_PATH_PROPERTY, config.getZipPath().toString()))); config.setDistributionSha256Sum(getProperty(DISTRIBUTION_SHA_256_SUM, "")); + config.setDistributionSha512Sum(getProperty(DISTRIBUTION_SHA_512_SUM, "")); config.setAlwaysUnpack(Boolean.parseBoolean(getProperty(ALWAYS_UNPACK, Boolean.FALSE.toString()))); config.setAlwaysDownload(Boolean.parseBoolean(getProperty(ALWAYS_DOWNLOAD, Boolean.FALSE.toString()))); } catch (Exception e) { diff --git a/maven-wrapper/src/test/java/org/apache/maven/wrapper/HashAlgorithmVerifierTest.java b/maven-wrapper/src/test/java/org/apache/maven/wrapper/HashAlgorithmVerifierTest.java index 498ee563..b34a42db 100644 --- a/maven-wrapper/src/test/java/org/apache/maven/wrapper/HashAlgorithmVerifierTest.java +++ b/maven-wrapper/src/test/java/org/apache/maven/wrapper/HashAlgorithmVerifierTest.java @@ -57,6 +57,15 @@ void sha256SumsMatch() throws Exception { "7e0c63c6a99639e57cc64375d6717d72e301d8ab829fef2e145ee860317bc3cb"); } + @Test + void sha512SumsMatch() throws Exception { + verifier.verify( + file, + "property", + Verifier.SHA_512_ALGORITHM, + "256cdc53261371d6f6fefd92e99d85df5295d1f83ab826106768094a34e6f1b0eb4f7c30e75ada80218ed5bb384bdce334a6697354eef561f50adfc2113c881d"); + } + @Test void sha256SumsDoNotMatch() throws Exception { try { @@ -74,4 +83,22 @@ void sha256SumsDoNotMatch() throws Exception { e.getMessage()); } } + + @Test + void sha512SumsDoNotMatch() throws Exception { + try { + verifier.verify( + file, + "prop", + Verifier.SHA_512_ALGORITHM, + "03e2d65d4483a3396980629f260e25cac0d8b6f7f2791e4dc20bc83f9514db8d0f05b0479e699a5f34679250c49c8e52e961262ded468a20de0be254d8207076"); + fail("Expected RuntimeException"); + } catch (RuntimeException e) { + assertEquals( + "Failed to validate Maven distribution SHA-512, your Maven " + + "distribution might be compromised. If you updated your Maven version, " + + "you need to update the specified prop property.", + e.getMessage()); + } + } } diff --git a/maven-wrapper/src/test/java/org/apache/maven/wrapper/InstallerTest.java b/maven-wrapper/src/test/java/org/apache/maven/wrapper/InstallerTest.java index 04731eaa..f456415f 100644 --- a/maven-wrapper/src/test/java/org/apache/maven/wrapper/InstallerTest.java +++ b/maven-wrapper/src/test/java/org/apache/maven/wrapper/InstallerTest.java @@ -91,6 +91,7 @@ void setup() throws Exception { configuration.setAlwaysDownload(false); configuration.setAlwaysUnpack(false); configuration.setDistributionSha256Sum(""); + configuration.setDistributionSha512Sum(""); distributionDir = testDir.resolve("someDistPath"); mavenHomeDir = distributionDir.resolve("maven-0.9"); zipStore = testDir.resolve("zips"); @@ -120,7 +121,7 @@ private void createTestZip(Path zipDestination) throws Exception { writer.write("something"); } try (OutputStream os = Files.newOutputStream(mavenLib); - JarOutputStream jar = new JarOutputStream(os, new Manifest())) { + JarOutputStream jar = new JarOutputStream(os, new Manifest())) { jar.putNextEntry(new ZipEntry("test")); jar.closeEntry(); } @@ -227,7 +228,7 @@ void testZipSlip() throws URISyntaxException { public void zipTo(final Path directoryToZip, final Path zipFile) throws IOException { // Creating a ZipOutputStream by wrapping a OutputStream try (OutputStream fos = Files.newOutputStream(zipFile); - ZipOutputStream zos = new ZipOutputStream(fos)) { + ZipOutputStream zos = new ZipOutputStream(fos)) { // Walk the tree structure using WalkFileTree method Files.walkFileTree(directoryToZip, new SimpleFileVisitor() { @Override diff --git a/pom.xml b/pom.xml index 4b547d42..a7378b39 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ under the License. org.apache.maven.wrapper maven-wrapper-parent - 3.3.5-SNAPSHOT + 3.4.0-SNAPSHOT pom Apache Maven Wrapper diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md index 471a0216..fead08f8 100644 --- a/src/site/markdown/index.md +++ b/src/site/markdown/index.md @@ -192,10 +192,10 @@ used. To avoid supply-chain-attacks by downloading a corrupted artifact, it is possible to specify checksums for both the *maven-wrapper.jar* and the downloaded distribution. To apply verification, add the expected -file's SHA-256 sum in hex notation, using only small caps, to +file's SHA-256 or SHA-512 sum in hex notation, using only small caps, to `maven-wrapper.properties`. The property for validating the -*maven-wrapper.jar* file is named `wrapperSha256Sum` whereas the -distribution file property is named `distributionSha256Sum`. +*maven-wrapper.jar* file are named `wrapperSha256Sum` and `wrapperSha512Sum` whereas the +distribution file property are named `distributionSha256Sum` and `distributionSha512Sum`. ## Internals