Allow sha512 checksum without filename for maven plugins (#52668)

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
This commit is contained in:
Ryan Ernst 2020-02-24 13:33:50 -08:00 committed by Ryan Ernst
parent 4cae4ded4b
commit a1e7429ccc
2 changed files with 55 additions and 12 deletions

View File

@ -561,21 +561,24 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
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);

View File

@ -115,6 +115,7 @@ import static org.hamcrest.Matchers.empty;
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 {
@ -1113,6 +1114,45 @@ public class InstallPluginCommandTests extends ESTestCase {
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);
assertThat(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()