You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ra...@apache.org on 2018/10/16 13:21:29 UTC
[cloudstack] branch 4.11 updated: Add checksum sanity validation on
template registration (#2902)
This is an automated email from the ASF dual-hosted git repository.
rafael pushed a commit to branch 4.11
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.11 by this push:
new 9003c7b Add checksum sanity validation on template registration (#2902)
9003c7b is described below
commit 9003c7bfdce9586aaeef19b1aea372b4fcfdb9b4
Author: Nicolas Vazquez <ni...@gmail.com>
AuthorDate: Tue Oct 16 10:21:20 2018 -0300
Add checksum sanity validation on template registration (#2902)
* Add checksum sanity validation on template registration
* Refactor
* Rename checksum sanity method
---
.../cloud/template/HypervisorTemplateAdapter.java | 3 +++
.../cloudstack/utils/security/DigestHelper.java | 27 +++++++++++++++++--
.../utils/security/DigestHelperTest.java | 30 ++++++++++++++++++++++
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
index bfa73af..8aa2166 100644
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -39,6 +39,7 @@ import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplat
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
+import org.apache.cloudstack.utils.security.DigestHelper;
import org.apache.log4j.Logger;
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd;
@@ -155,6 +156,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
String url = profile.getUrl();
UriUtils.validateUrl(ImageFormat.ISO.getFileExtension(), url);
if (cmd.isDirectDownload()) {
+ DigestHelper.validateChecksumString(cmd.getChecksum());
Long templateSize = performDirectDownloadUrlValidation(url);
profile.setSize(templateSize);
}
@@ -170,6 +172,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
String url = profile.getUrl();
UriUtils.validateUrl(cmd.getFormat(), url);
if (cmd.isDirectDownload()) {
+ DigestHelper.validateChecksumString(cmd.getChecksum());
Long templateSize = performDirectDownloadUrlValidation(url);
profile.setSize(templateSize);
}
diff --git a/utils/src/main/java/org/apache/cloudstack/utils/security/DigestHelper.java b/utils/src/main/java/org/apache/cloudstack/utils/security/DigestHelper.java
index 67adf74..40b0c1c 100644
--- a/utils/src/main/java/org/apache/cloudstack/utils/security/DigestHelper.java
+++ b/utils/src/main/java/org/apache/cloudstack/utils/security/DigestHelper.java
@@ -16,6 +16,8 @@
// under the License.
package org.apache.cloudstack.utils.security;
+import org.apache.commons.lang.StringUtils;
+
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
@@ -70,9 +72,9 @@ public class DigestHelper {
return checksum;
}
- static final Map<String, Integer> paddingLengths = creatPaddingLengths();
+ static final Map<String, Integer> paddingLengths = getChecksumLengthsMap();
- private static final Map<String, Integer> creatPaddingLengths() {
+ private static final Map<String, Integer> getChecksumLengthsMap() {
Map<String, Integer> map = new HashMap<>();
map.put("MD5", 32);
map.put("SHA-1", 40);
@@ -93,4 +95,25 @@ public class DigestHelper {
}
return true;
}
+
+ /**
+ * Checksum sanity for not empty checksum. Expected format: {ALG}HASH
+ * If ALG is missing, MD5 is assumed as default
+ * Hash length is verified, depending on the algorithm.
+ * IllegalArgumentException is thrown in case of malformed checksums
+ */
+ public static void validateChecksumString(String checksum) {
+ if(StringUtils.isNotEmpty(checksum)) {
+ ChecksumValue checksumValue = new ChecksumValue(checksum);
+ String digest = checksumValue.getChecksum();
+ Map<String, Integer> map = getChecksumLengthsMap();
+ if (!map.containsKey(checksumValue.getAlgorithm())) {
+ throw new IllegalArgumentException("Algorithm " + checksumValue.getAlgorithm() + " was provided but it is not one of the supported algorithms");
+ }
+ Integer expectedLength = map.get(checksumValue.getAlgorithm());
+ if (digest.length() != expectedLength) {
+ throw new IllegalArgumentException("Checksum digest length should be " + expectedLength + " instead of " + digest.length());
+ }
+ }
+ }
}
diff --git a/utils/src/test/java/org/apache/cloudstack/utils/security/DigestHelperTest.java b/utils/src/test/java/org/apache/cloudstack/utils/security/DigestHelperTest.java
index 4540882..4a6e3f7 100644
--- a/utils/src/test/java/org/apache/cloudstack/utils/security/DigestHelperTest.java
+++ b/utils/src/test/java/org/apache/cloudstack/utils/security/DigestHelperTest.java
@@ -32,8 +32,10 @@ public class DigestHelperTest {
private final static String INPUT_STRING_NO2 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789b\n";
private final static String INPUT_STRING_NO3 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789h\n";
private final static String SHA256_CHECKSUM = "{SHA-256}c6ab15af7842d23d3c06c138b53a7d09c5e351a79c4eb3c8ca8d65e5ce8900ab";
+ private final static String SHA256_NO_PREFIX_CHECKSUM = "c6ab15af7842d23d3c06c138b53a7d09c5e351a79c4eb3c8ca8d65e5ce8900ab";
private final static String SHA1_CHECKSUM = "{SHA-1}49e4b2f4292b63e88597c127d11bc2cc0f2ca0ff";
private final static String MD5_CHECKSUM = "{MD5}d141a8eeaf6bba779d1d1dc5102a81c5";
+ private final static String MD5_NO_PREFIX_CHECKSUM = "d141a8eeaf6bba779d1d1dc5102a81c5";
private final static String ZERO_PADDED_MD5_CHECKSUM = "{MD5}0e51dfa74b87f19dd5e0124d6a2195e3";
private final static String ZERO_PADDED_SHA256_CHECKSUM = "{SHA-256}08b5ae0c7d7d45d8ed406d7c3c7da695b81187903694314d97f8a37752a6b241";
private static final String MD5 = "MD5";
@@ -97,6 +99,34 @@ public class DigestHelperTest {
public void reset() throws IOException {
inputStream.reset();
}
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testChecksumSanityNoPrefixWrongAlgorithm() {
+ DigestHelper.validateChecksumString(SHA256_NO_PREFIX_CHECKSUM);
+ }
+
+ @Test
+ public void testChecksumSanityNoPrefix() {
+ DigestHelper.validateChecksumString(MD5_NO_PREFIX_CHECKSUM);
+ }
+
+ @Test
+ public void testChecksumSanityPrefixEmptyAlgorithm() {
+ String checksum = "{}" + MD5_NO_PREFIX_CHECKSUM;
+ DigestHelper.validateChecksumString(checksum);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testChecksumSanityPrefixWrongAlgorithm() {
+ String checksum = "{MD5}" + SHA256_NO_PREFIX_CHECKSUM;
+ DigestHelper.validateChecksumString(checksum);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testChecksumSanityPrefixWrongChecksumLength() {
+ String checksum = SHA256_CHECKSUM + "XXXXX";
+ DigestHelper.validateChecksumString(checksum);
+ }
}
//Generated with love by TestMe :) Please report issues and submit feature requests at: http://weirddev.com/forum#!/testme
\ No newline at end of file