From 70e61bd3d51f9ff4a139ed3c9521ab93c68051b4 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Fri, 21 Feb 2020 15:28:15 -0800 Subject: [PATCH 1/2] Allow sha512 checksum without filename for maven plugins When installing plugins from remote sources, either the Elastic download service, or maven, a checksum file is downloaded and checked against the downloaded zip. The current format for official plugins is to use a sha512 checksum which includes the zip filename. This format matches that from sha512sum, and allows using the --check argument there to verify the checksum manually. However, when generating checksum files with maven and gradle, the filename is not included. This commit relaxes the requirement the filename existing within the sha512 checksum file for maven plugins. We continue to strictly enforce official plugins have the existing format of the file. closes #52413 --- .../plugins/InstallPluginCommand.java | 27 +++++++++-------- .../plugins/InstallPluginCommandTests.java | 29 +++++++++++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java index f034e8ce6310d..ced76ee3b52d8 100644 --- a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java +++ b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java @@ -545,21 +545,24 @@ private Path downloadAndValidate( final BufferedReader checksumReader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); final String checksumLine = checksumReader.readLine(); final String[] fields = checksumLine.split(" {2}"); - if (fields.length != 2) { + if (officialPlugin && fields.length != 2 || officialPlugin == false && fields.length > 2) { throw new UserException(ExitCodes.IO_ERROR, "Invalid checksum file at " + checksumUrl); } expectedChecksum = fields[0]; - final String[] segments = URI.create(urlString).getPath().split("/"); - final String expectedFile = segments[segments.length - 1]; - if (fields[1].equals(expectedFile) == false) { - final String message = String.format( - Locale.ROOT, - "checksum file at [%s] is not for this plugin, expected [%s] but was [%s]", - checksumUrl, - expectedFile, - fields[1] - ); - throw new UserException(ExitCodes.IO_ERROR, message); + if (fields.length == 2) { + // checksum line contains filename as well + final String[] segments = URI.create(urlString).getPath().split("/"); + final String expectedFile = segments[segments.length - 1]; + if (fields[1].equals(expectedFile) == false) { + final String message = String.format( + Locale.ROOT, + "checksum file at [%s] is not for this plugin, expected [%s] but was [%s]", + checksumUrl, + expectedFile, + fields[1] + ); + throw new UserException(ExitCodes.IO_ERROR, message); + } } if (checksumReader.readLine() != null) { throw new UserException(ExitCodes.IO_ERROR, "Invalid checksum file at " + checksumUrl); diff --git a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java index 02a2c860859e6..a2525a49324c1 100644 --- a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java +++ b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java @@ -1109,6 +1109,35 @@ public void testMavenSha1Backcompat() throws Exception { assertTrue(terminal.getOutput(), terminal.getOutput().contains("sha512 not found, falling back to sha1")); } + public void testMavenChecksumWithoutFilename() throws Exception { + String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip"; + MessageDigest digest = MessageDigest.getInstance("SHA-512"); + assertInstallPluginFromUrl("mygroup:myplugin:1.0.0", "myplugin", url, null, false, ".sha512", checksum(digest), null, (b, p) -> null); + } + + public void testOfficialChecksumWithoutFilename() throws Exception { + String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + + Build.CURRENT.getQualifiedVersion() + + ".zip"; + MessageDigest digest = MessageDigest.getInstance("SHA-512"); + UserException e = expectThrows( + UserException.class, + () -> assertInstallPluginFromUrl( + "analysis-icu", + "analysis-icu", + url, + null, + false, + ".sha512", + checksum(digest), + null, + (b, p) -> null + ) + ); + assertEquals(ExitCodes.IO_ERROR, e.exitCode); + assertTrue(e.getMessage(), e.getMessage().startsWith("Invalid checksum file")); + } + public void testOfficialShaMissing() throws Exception { String url = "https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-icu/analysis-icu-" + Build.CURRENT.getQualifiedVersion() From 381a511b3a9249387a663d298544642817871608 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 24 Feb 2020 11:11:22 -0800 Subject: [PATCH 2/2] use startsWith and format lines --- .../plugins/InstallPluginCommandTests.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java index a2525a49324c1..dbcfb9e66d9ad 100644 --- a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java +++ b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java @@ -114,6 +114,7 @@ import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; @LuceneTestCase.SuppressFileSystems("*") public class InstallPluginCommandTests extends ESTestCase { @@ -1112,7 +1113,17 @@ public void testMavenSha1Backcompat() throws Exception { public void testMavenChecksumWithoutFilename() throws Exception { String url = "https://repo1.maven.org/maven2/mygroup/myplugin/1.0.0/myplugin-1.0.0.zip"; MessageDigest digest = MessageDigest.getInstance("SHA-512"); - assertInstallPluginFromUrl("mygroup:myplugin:1.0.0", "myplugin", url, null, false, ".sha512", checksum(digest), null, (b, p) -> null); + assertInstallPluginFromUrl( + "mygroup:myplugin:1.0.0", + "myplugin", + url, + null, + false, + ".sha512", + checksum(digest), + null, + (b, p) -> null + ); } public void testOfficialChecksumWithoutFilename() throws Exception { @@ -1135,7 +1146,7 @@ public void testOfficialChecksumWithoutFilename() throws Exception { ) ); assertEquals(ExitCodes.IO_ERROR, e.exitCode); - assertTrue(e.getMessage(), e.getMessage().startsWith("Invalid checksum file")); + assertThat(e.getMessage(), startsWith("Invalid checksum file")); } public void testOfficialShaMissing() throws Exception {