From 018023c1ef7fc5216a607e40811ff20f185d295c Mon Sep 17 00:00:00 2001 From: Rajani Karuturi Date: Thu, 19 Mar 2015 11:54:51 +0530 Subject: [PATCH] volume upload: added validation for file formats merged TemplateUtils and ImageStoreUtil to a singe ImageStoreUtil also added a unittest for ImageStoreUtil --- .../template/HttpTemplateDownloader.java | 4 +- .../cloud/storage/VolumeApiServiceImpl.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 2 +- .../resource/HttpUploadServerHandler.java | 10 +++ .../resource/NfsSecondaryStorageResource.java | 14 ++++ utils/src/com/cloud/utils/ImageStoreUtil.java | 39 ----------- .../ImageStoreUtil.java} | 65 +++++++++++-------- .../utils/imagestore/ImageStoreUtilTest.java | 38 +++++++++++ 8 files changed, 105 insertions(+), 69 deletions(-) delete mode 100644 utils/src/com/cloud/utils/ImageStoreUtil.java rename utils/src/org/apache/cloudstack/utils/{template/TemplateUtils.java => imagestore/ImageStoreUtil.java} (61%) create mode 100644 utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java diff --git a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java index 5644af4f8e8..632a80963e9 100644 --- a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java +++ b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java @@ -28,6 +28,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.Date; +import org.apache.cloudstack.utils.imagestore.ImageStoreUtil; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; @@ -45,7 +46,6 @@ import org.apache.log4j.Logger; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; -import org.apache.cloudstack.utils.template.TemplateUtils; import com.cloud.agent.api.storage.Proxy; import com.cloud.storage.StorageLayer; @@ -259,7 +259,7 @@ public class HttpTemplateDownloader extends ManagedContextRunnable implements Te } catch (URISyntaxException e) { s_logger.warn("Invalid download url: " + getDownloadUrl() + ", This should not happen since we have validated the url before!!"); } - String unsupportedFormat = TemplateUtils.checkTemplateFormat(file.getAbsolutePath(), uripath); + String unsupportedFormat = ImageStoreUtil.checkTemplateFormat(file.getAbsolutePath(), uripath); if (unsupportedFormat == null || !unsupportedFormat.isEmpty()) { try { request.abort(); diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 567a7426b5d..4ff7686cab8 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -29,7 +29,6 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; import com.cloud.utils.EncryptionUtil; -import com.cloud.utils.ImageStoreUtil; import com.cloud.utils.db.TransactionCallbackWithException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -39,6 +38,7 @@ import org.apache.cloudstack.api.response.GetUploadParamsResponse; 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.imagestore.ImageStoreUtil; import org.apache.log4j.Logger; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 9747ad00f6f..10ff77f5dd2 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -35,13 +35,13 @@ import javax.naming.ConfigurationException; import com.cloud.storage.ImageStoreUploadMonitorImpl; import com.cloud.utils.EncryptionUtil; -import com.cloud.utils.ImageStoreUtil; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import org.apache.cloudstack.api.command.user.template.GetUploadParamsForTemplateCmd; import org.apache.cloudstack.api.response.GetUploadParamsResponse; import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand; +import org.apache.cloudstack.utils.imagestore.ImageStoreUtil; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.SecurityChecker.AccessType; diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java index 44a2b6043fc..4a3fa86d9d8 100644 --- a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java +++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/HttpUploadServerHandler.java @@ -28,6 +28,8 @@ import java.util.Map; import java.util.Map.Entry; import org.apache.cloudstack.storage.template.UploadEntity; +import org.apache.cloudstack.utils.imagestore.ImageStoreUtil; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.cloud.exception.InvalidParameterValueException; @@ -228,6 +230,14 @@ public class HttpUploadServerHandler extends SimpleChannelInboundHandler maxSize) { diff --git a/utils/src/com/cloud/utils/ImageStoreUtil.java b/utils/src/com/cloud/utils/ImageStoreUtil.java deleted file mode 100644 index 52f13244c16..00000000000 --- a/utils/src/com/cloud/utils/ImageStoreUtil.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ -package com.cloud.utils; - -import org.apache.log4j.Logger; - -public class ImageStoreUtil { - public static final Logger s_logger = Logger.getLogger(ImageStoreUtil.class.getName()); - - public static String generatePostUploadUrl(String ssvmUrlDomain, String ipAddress, String uuid) { - String hostname = ipAddress; - - //if ssvm url domain is present, use it to construct hostname in the format 1-2-3-4.domain - // if the domain name is not present, ssl validation fails and has to be ignored - if(StringUtils.isNotBlank(ssvmUrlDomain)) { - hostname = ipAddress.replace(".", "-"); - hostname = hostname + ssvmUrlDomain.substring(1); - } - - //only https works with postupload and url format is fixed - return "https://" + hostname + "/upload/" + uuid; - } -} diff --git a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java b/utils/src/org/apache/cloudstack/utils/imagestore/ImageStoreUtil.java similarity index 61% rename from utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java rename to utils/src/org/apache/cloudstack/utils/imagestore/ImageStoreUtil.java index 53aa9113a9b..ed1336027eb 100644 --- a/utils/src/org/apache/cloudstack/utils/template/TemplateUtils.java +++ b/utils/src/org/apache/cloudstack/utils/imagestore/ImageStoreUtil.java @@ -1,30 +1,43 @@ -// -// 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. -// - -package org.apache.cloudstack.utils.template; - -import org.apache.log4j.Logger; +/* + * 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. + */ +package org.apache.cloudstack.utils.imagestore; import com.cloud.utils.script.Script; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; -public class TemplateUtils { - public static final Logger s_logger = Logger.getLogger(TemplateUtils.class.getName()); +public class ImageStoreUtil { + public static final Logger s_logger = Logger.getLogger(ImageStoreUtil.class.getName()); + + public static String generatePostUploadUrl(String ssvmUrlDomain, String ipAddress, String uuid) { + String hostname = ipAddress; + + //if ssvm url domain is present, use it to construct hostname in the format 1-2-3-4.domain + // if the domain name is not present, ssl validation fails and has to be ignored + if(StringUtils.isNotBlank(ssvmUrlDomain)) { + hostname = ipAddress.replace(".", "-"); + hostname = hostname + ssvmUrlDomain.substring(1); + } + + //only https works with postupload and url format is fixed + return "https://" + hostname + "/upload/" + uuid; + } // given a path, returns empty if path is supported image, and the file type if unsupported // this is meant to catch things like accidental upload of ASCII text .vmdk descriptor @@ -75,7 +88,7 @@ public class TemplateUtils { return output; } - public static boolean isCorrectExtension(String path, String ext) { + private static boolean isCorrectExtension(String path, String ext) { if (path.toLowerCase().endsWith(ext) || path.toLowerCase().endsWith(ext + ".gz") || path.toLowerCase().endsWith(ext + ".bz2") @@ -85,7 +98,7 @@ public class TemplateUtils { return false; } - public static boolean isCompressedExtension(String path) { + private static boolean isCompressedExtension(String path) { if (path.toLowerCase().endsWith(".gz") || path.toLowerCase().endsWith(".bz2") || path.toLowerCase().endsWith(".zip")) { diff --git a/utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java b/utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java new file mode 100644 index 00000000000..e1b55780442 --- /dev/null +++ b/utils/test/org/apache/cloudstack/utils/imagestore/ImageStoreUtilTest.java @@ -0,0 +1,38 @@ +package org.apache.cloudstack.utils.imagestore; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; + +public class ImageStoreUtilTest { + + @Test + public void testgeneratePostUploadUrl() throws MalformedURLException { + String ssvmdomain = "*.realhostip.com"; + String ipAddress = "10.147.28.14"; + String uuid = UUID.randomUUID().toString(); + + //ssvm domain is not set + String url = ImageStoreUtil.generatePostUploadUrl(null, ipAddress, uuid); + assertPostUploadUrl(url, ipAddress, uuid); + + //ssvm domain is set to empty value + url = ImageStoreUtil.generatePostUploadUrl("", ipAddress, uuid); + assertPostUploadUrl(url, ipAddress, uuid); + + //ssvm domain is set to a valid value + url = ImageStoreUtil.generatePostUploadUrl(ssvmdomain, ipAddress, uuid); + assertPostUploadUrl(url, ipAddress.replace(".", "-") + ssvmdomain.substring(1), uuid); + } + + private void assertPostUploadUrl(String urlStr, String domain, String uuid) throws MalformedURLException { + URL url = new URL(urlStr); + Assert.assertNotNull(url); + Assert.assertEquals(url.getHost(), domain); + Assert.assertEquals(url.getPath(), "/upload/" + uuid); + } + +} \ No newline at end of file