diff options
Diffstat (limited to 'openecomp-be/lib')
10 files changed, 209 insertions, 212 deletions
diff --git a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/utils/CommonUtil.java b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/utils/CommonUtil.java index ae7d44efd8..8610ecb74b 100644 --- a/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/utils/CommonUtil.java +++ b/openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/utils/CommonUtil.java @@ -20,62 +20,50 @@ package org.openecomp.sdc.common.utils; import com.google.common.collect.Multimap; - +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.openecomp.core.utilities.file.FileContentHandler; -import org.openecomp.core.utilities.file.FileUtils; import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum; import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.common.errors.ErrorCategory; import org.openecomp.sdc.common.errors.ErrorCode; import org.openecomp.sdc.common.errors.Messages; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipInputStream; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; public class CommonUtil { - static final String DEFAULT = "default"; - static final String _DEFAULT = "_default"; private CommonUtil() { // prevent instantiation } - public static FileContentHandler validateAndUploadFileContent(OnboardingTypesEnum type, - byte[] uploadedFileData) - throws IOException { - return getFileContentMapFromOrchestrationCandidateZipAndValidateNoFolders(type, - uploadedFileData); - } - /** - * Gets files out of the zip AND validates zip is flat (no folders) + * Reads the files from the zip AND validates zip is flat (no folders). * - * @param uploadFileData zip file + * @param type the onboarding type + * @param uploadedFileData zip file bytes * @return FileContentHandler if input is valid and has no folders + * @throws IOException when the zip could not be read */ - private static FileContentHandler getFileContentMapFromOrchestrationCandidateZipAndValidateNoFolders( - OnboardingTypesEnum type, byte[] uploadFileData) - throws IOException { - Pair<FileContentHandler, List<String>> pair = - getFileContentMapFromOrchestrationCandidateZip(uploadFileData); - + public static FileContentHandler validateAndUploadFileContent(final OnboardingTypesEnum type, + final byte[] uploadedFileData) throws IOException { + final Pair<FileContentHandler, List<String>> pair; + try { + pair = getFileContentMapFromOrchestrationCandidateZip(uploadedFileData); + } catch (final ZipException e) { + throw new IOException(e); + } if (isFileOriginFromZip(type.toString())) { validateNoFolders(pair.getRight()); } @@ -84,47 +72,22 @@ public class CommonUtil { } public static Pair<FileContentHandler, List<String>> getFileContentMapFromOrchestrationCandidateZip( - byte[] uploadFileData) - throws IOException { - ZipEntry zipEntry; - List<String> folderList = new ArrayList<>(); - FileContentHandler mapFileContent = new FileContentHandler(); - try (ByteArrayInputStream in = new ByteArrayInputStream(uploadFileData); - ZipInputStream inputZipStream = new ZipInputStream(in)) { - byte[] fileByteContent; - String currentEntryName; - - while ((zipEntry = inputZipStream.getNextEntry()) != null) { - assertEntryNotVulnerable(zipEntry); - currentEntryName = zipEntry.getName(); - fileByteContent = FileUtils.toByteArray(inputZipStream); - - int index = lastIndexFileSeparatorIndex(currentEntryName); - if (index != -1) { - folderList.add(currentEntryName); - } - if (isFile(currentEntryName)) { - mapFileContent.addFile(currentEntryName, fileByteContent); - } + byte[] uploadFileData) throws ZipException { + final Map<String, byte[]> zipFileMap = ZipUtils.readZip(uploadFileData, true); + final List<String> folderList = new ArrayList<>(); + final FileContentHandler mapFileContent = new FileContentHandler(); + + zipFileMap.forEach((key, value) -> { + if (value == null) { + folderList.add(key); + } else { + mapFileContent.addFile(key, value); } - - } catch (RuntimeException exception) { - throw new IOException(exception); - } + }); return new ImmutablePair<>(mapFileContent, folderList); } - private static void assertEntryNotVulnerable(ZipEntry entry) throws ZipException { - if (entry.getName().contains("../")) { - throw new ZipException("Path traversal attempt discovered."); - } - } - - private static boolean isFile(String currentEntryName) { - return !(currentEntryName.endsWith("\\") || currentEntryName.endsWith("/")); - } - private static void validateNoFolders(List<String> folderList) { if (CollectionUtils.isNotEmpty(folderList)) { throw new CoreException((new ErrorCode.ErrorCodeBuilder()) @@ -134,19 +97,6 @@ public class CommonUtil { } } - private static int lastIndexFileSeparatorIndex(String filePath) { - int length = filePath.length() - 1; - - for (int i = length; i >= 0; i--) { - char currChar = filePath.charAt(i); - if (currChar == '/' || currChar == File.separatorChar || currChar == File.pathSeparatorChar) { - return i; - } - } - // if we've reached to the start of the string and didn't find file separator - return -1 - return -1; - } - private static boolean validateFilesExtensions(Set<String> allowedExtensions, FileContentHandler files) { for (String fileName : files.getFileList()) { diff --git a/openecomp-be/lib/openecomp-common-lib/src/test/java/org/openecomp/sdc/common/utils/CommonUtilTest.java b/openecomp-be/lib/openecomp-common-lib/src/test/java/org/openecomp/sdc/common/utils/CommonUtilTest.java index bc0bd137a0..119616a9be 100644 --- a/openecomp-be/lib/openecomp-common-lib/src/test/java/org/openecomp/sdc/common/utils/CommonUtilTest.java +++ b/openecomp-be/lib/openecomp-common-lib/src/test/java/org/openecomp/sdc/common/utils/CommonUtilTest.java @@ -16,23 +16,21 @@ package org.openecomp.sdc.common.utils; -import org.testng.annotations.Test; +import static org.onap.sdc.tosca.services.CommonUtil.DEFAULT; +import static org.onap.sdc.tosca.services.CommonUtil.UNDERSCORE_DEFAULT; +import static org.testng.Assert.assertTrue; import java.util.HashMap; import java.util.Map; - -import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; public class CommonUtilTest { @Test public void testGetObjectAsMap() { - Map<String, String> obj = new HashMap<>(1); - obj.put(CommonUtil.DEFAULT, ""); - Map<String, Object> newMap = CommonUtil.getObjectAsMap(obj); - - boolean exists = newMap.containsKey(CommonUtil._DEFAULT); - - assertTrue(exists); + final Map<String, String> obj = new HashMap<>(1); + obj.put(DEFAULT, ""); + assertTrue(CommonUtil.getObjectAsMap(obj).containsKey(UNDERSCORE_DEFAULT)); } + } diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/pom.xml b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/pom.xml index ce88037706..b86964f61f 100644 --- a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/pom.xml +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/pom.xml @@ -66,6 +66,18 @@ <version>${commons.codec.version}</version> </dependency> <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest</artifactId> + <version>${hamcrest.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-library</artifactId> + <version>${hamcrest.version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> @@ -85,6 +97,12 @@ <artifactId>openecomp-sdc-logging-api</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>common-app-api</artifactId> + <version>${project.version}</version> + <scope>compile</scope> + </dependency> </dependencies> </project> diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java index c807d1b979..31338dcda4 100644 --- a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/main/java/org/openecomp/core/utilities/file/FileUtils.java @@ -16,11 +16,6 @@ package org.openecomp.core.utilities.file; -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; -import org.onap.sdc.tosca.services.YamlUtil; -import org.openecomp.core.utilities.json.JsonUtil; - import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; @@ -28,11 +23,20 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.file.Path; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Function; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipInputStream; -import java.util.*; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.onap.sdc.tosca.services.YamlUtil; +import org.openecomp.core.utilities.json.JsonUtil; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; /** * The type File utils. @@ -220,26 +224,14 @@ public class FileUtils { * * @param zipData the zip data * @return the file content map from zip - * @throws IOException the io exception + * @throws ZipException when an error occurs while extracting zip files */ - public static FileContentHandler getFileContentMapFromZip(byte[] zipData) throws IOException { - - try (ZipInputStream inputZipStream = new ZipInputStream(new ByteArrayInputStream(zipData))) { - - FileContentHandler mapFileContent = new FileContentHandler(); - - ZipEntry zipEntry; - - while ((zipEntry = inputZipStream.getNextEntry()) != null) { - assertEntryNotVulnerable(zipEntry); - mapFileContent.addFile(zipEntry.getName(), FileUtils.toByteArray(inputZipStream)); - } - - return mapFileContent; - - } catch (RuntimeException exception) { - throw new IOException(exception); - } + public static FileContentHandler getFileContentMapFromZip(byte[] zipData) + throws ZipException { + final Map<String, byte[]> zipFileAndByteMap = ZipUtils.readZip(zipData, true); + final FileContentHandler mapFileContent = new FileContentHandler(); + mapFileContent.setFiles(zipFileAndByteMap); + return mapFileContent; } @@ -286,20 +278,28 @@ public class FileUtils { * @return a map containing file names and their absolute paths * @throws IOException the io exception */ - public static Map<String, String> writeFilesFromFileContentHandler(FileContentHandler - fileContentHandler, - Path dir) - throws IOException { - + public static Map<String, String> writeFilesFromFileContentHandler(final FileContentHandler fileContentHandler, + final Path dir) throws IOException { File file; - File dirFile = dir.toFile(); - Map<String, String> filePaths = new HashMap<>(); - for (Map.Entry<String, byte[]> fileEntry : fileContentHandler.getFiles().entrySet()) { + final File dirFile = dir.toFile(); + final Map<String, String> filePaths = new HashMap<>(); + for (final Map.Entry<String, byte[]> fileEntry : fileContentHandler.getFiles().entrySet()) { file = new File(dirFile, fileEntry.getKey()); - file.getParentFile().mkdirs(); filePaths.put(fileEntry.getKey(), file.getAbsolutePath()); - try (FileOutputStream fop = new FileOutputStream(file.getAbsolutePath());) { - fop.write(fileEntry.getValue()); + final byte[] fileBytes = fileEntry.getValue(); + if (fileBytes == null) { + if (!file.exists() && !file.mkdirs()) { + throw new IOException("Could not create directory " + file.getAbsolutePath()); + } + continue; + } else { + if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { + throw new IOException("Could not create parent directory for " + file.getAbsolutePath()); + } + } + + try (final FileOutputStream fop = new FileOutputStream(file.getAbsolutePath());) { + fop.write(fileBytes); fop.flush(); } } @@ -318,10 +318,4 @@ public class FileUtils { fileExtension.equalsIgnoreCase(FileExtension.YAML.getDisplayName()); } - private static void assertEntryNotVulnerable(ZipEntry entry) throws ZipException { - if (entry.getName().contains("../")) { - throw new ZipException("Path traversal attempt discovered."); - } - } - } diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java index a4928ac739..facfe57622 100644 --- a/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-utilities-lib/src/test/java/org/openecomp/core/utilities/file/FileUtilsTest.java @@ -17,8 +17,12 @@ package org.openecomp.core.utilities.file; import static junit.framework.TestCase.assertTrue; -import static org.junit.Assert.assertEquals; +import static org.hamcrest.Matchers.aMapWithSize; +import static org.hamcrest.Matchers.anEmptyMap; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; import java.io.File; import java.io.IOException; @@ -34,6 +38,7 @@ import java.util.stream.Stream; import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Test; +import org.openecomp.sdc.common.zip.exception.ZipException; /** * @author EVITALIY @@ -74,25 +79,22 @@ public class FileUtilsTest { } @Test - public void testWriteFilesFromFileContentHandler() throws IOException { - Path dir = Files.createTempDirectory("CSAR_" + System.currentTimeMillis()); + public void testWriteFilesFromFileContentHandler() throws IOException, ZipException { + final Path tempDirectory = Files.createTempDirectory("CSAR_" + System.currentTimeMillis()); try { - byte[] uploadedFileData = IOUtils.toByteArray( - FileUtilsTest.class.getResource("resource-Spgw-csar-ZTE" + - ".csar")); - FileContentHandler contentMap = FileUtils.getFileContentMapFromZip(uploadedFileData); - Map<String, String> filePaths = FileUtils.writeFilesFromFileContentHandler(contentMap, - dir); - - assertFalse(filePaths.isEmpty()); - assertEquals(filePaths.size(), 18); - for (Map.Entry<String, String> fileEntry : filePaths.entrySet()) { - File f = new File(fileEntry.getValue()); - assertTrue(f.exists()); + byte[] uploadedFileData = + IOUtils.toByteArray(FileUtilsTest.class.getResource("resource-Spgw-csar-ZTE.csar")); + final FileContentHandler contentMap = FileUtils.getFileContentMapFromZip(uploadedFileData); + final Map<String, String> filePaths = FileUtils.writeFilesFromFileContentHandler(contentMap, tempDirectory); + + assertThat("The file map should not be empty", filePaths, is(not(anEmptyMap()))); + assertThat("The file map should have size 20", filePaths, is(aMapWithSize(20))); + for (final Map.Entry<String, String> fileEntry : filePaths.entrySet()) { + final File f = new File(fileEntry.getValue()); + assertThat(String.format("The file '%s' is expected to", f.getAbsolutePath()), f.exists(), is(true)); } - } - finally { - org.apache.commons.io.FileUtils.deleteDirectory(dir.toFile()); + } finally { + org.apache.commons.io.FileUtils.deleteDirectory(tempDirectory.toFile()); } } @@ -106,22 +108,22 @@ public class FileUtilsTest { @Test public void testGetFileWithoutExtention() { - Assert.assertEquals(FileUtils.getFileWithoutExtention("test.txt"), "test"); + Assert.assertEquals("test", FileUtils.getFileWithoutExtention("test.txt")); } @Test public void testGetFileWithoutExtentionContainsNoExtension() { - Assert.assertEquals(FileUtils.getFileWithoutExtention("test"), "test"); + Assert.assertEquals("test", FileUtils.getFileWithoutExtention("test")); } @Test public void testGetFileExtention() { - Assert.assertEquals(FileUtils.getFileExtension("test.txt"), "txt"); + Assert.assertEquals("txt", FileUtils.getFileExtension("test.txt")); } @Test public void testGetNetworkPackageName() { - Assert.assertEquals(FileUtils.getNetworkPackageName("heat.zip"), "heat"); + Assert.assertEquals("heat", FileUtils.getNetworkPackageName("heat.zip")); } @Test @@ -191,6 +193,6 @@ public class FileUtilsTest { } Assert.assertNotNull(inputStream); - Assert.assertEquals(builder.toString(), "hello-test"); + Assert.assertEquals("hello-test", builder.toString()); } } diff --git a/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/external/artifact/MonitoringMibEnricher.java b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/external/artifact/MonitoringMibEnricher.java index dac9eae9ad..ca1fbe11b7 100644 --- a/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/external/artifact/MonitoringMibEnricher.java +++ b/openecomp-be/lib/openecomp-sdc-enrichment-lib/openecomp-sdc-enrichment-impl/src/main/java/org/openecomp/sdc/enrichment/impl/external/artifact/MonitoringMibEnricher.java @@ -16,6 +16,19 @@ package org.openecomp.sdc.enrichment.impl.external.artifact; +import static org.openecomp.sdc.tosca.services.ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME; +import static org.openecomp.sdc.tosca.services.ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import org.onap.sdc.tosca.datatypes.model.Directive; import org.onap.sdc.tosca.datatypes.model.NodeTemplate; import org.onap.sdc.tosca.datatypes.model.ServiceTemplate; @@ -29,6 +42,7 @@ import org.openecomp.core.model.types.ServiceArtifact; import org.openecomp.core.utilities.file.FileContentHandler; import org.openecomp.core.utilities.file.FileUtils; import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.datatypes.error.ErrorLevel; import org.openecomp.sdc.datatypes.error.ErrorMessage; import org.openecomp.sdc.enrichment.EnrichmentInfo; @@ -45,13 +59,6 @@ import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComponentEntity; import org.openecomp.sdc.vendorsoftwareproduct.dao.type.ComponentMonitoringUploadEntity; import org.openecomp.sdc.versioning.dao.types.Version; -import java.io.File; -import java.io.IOException; -import java.util.*; - -import static org.openecomp.sdc.tosca.services.ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME; -import static org.openecomp.sdc.tosca.services.ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME; - public class MonitoringMibEnricher implements ExternalArtifactEnricherInterface { private EnrichedServiceModelDao enrichedServiceModelDao; @@ -265,8 +272,8 @@ public class MonitoringMibEnricher implements ExternalArtifactEnricherInterface try { mibs = FileUtils .getFileContentMapFromZip(FileUtils.toByteArray(monitoringArtifactInfo.getContent())); - } catch (IOException ioException) { - log.error("Failed to get file content map from zip ", ioException); + } catch (ZipException ex) { + log.error("Failed to get file content map from zip ", ex); ErrorMessage.ErrorMessageUtil .addMessage(mibServiceArtifact.getName() + "." + type.name(), errors) .add(new ErrorMessage(ErrorLevel.ERROR, Messages.INVALID_ZIP_FILE.getErrorMessage())); diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java index e112ef432c..22ac1e8ed8 100644 --- a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java @@ -18,17 +18,21 @@ package org.openecomp.core.externaltesting.impl; import com.amdocs.zusammen.utils.fileutils.json.JsonUtil; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableSet; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; +import java.util.Map.Entry; import lombok.EqualsAndHashCode; -import org.apache.commons.io.IOUtils; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.onap.sdc.tosca.services.YamlUtil; import org.openecomp.core.externaltesting.api.*; import org.openecomp.core.externaltesting.errors.ExternalTestingException; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipException; import org.openecomp.sdc.heat.datatypes.manifest.FileData; import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent; import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager; @@ -58,7 +62,6 @@ import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; public class ExternalTestingManagerImpl implements ExternalTestingManager { @@ -97,6 +100,8 @@ public class ExternalTestingManagerImpl implements ExternalTestingManager { private static final String SDC_CSAR = "sdc-csar"; private static final String SDC_HEAT = "sdc-heat"; + private final ImmutableSet<String> relevantArchiveFileExtensionSet = + ImmutableSet.of("yaml", "meta", "yml", "json", "env"); private VersioningManager versioningManager; @@ -721,10 +726,8 @@ public class ExternalTestingManagerImpl implements ExternalTestingManager { private void processArchive(final VtpTestExecutionRequest test, final MultiValueMap<String, Object> body, final byte[] zip) { // We need to make one pass through the zip input stream. Pull out files that match our expectations into a temporary - // map that we can process over. These are not huge files so we shouldn't need to worry about memory. - - List<String> extensions = Arrays.asList(".yaml", ".meta", ".yml", ".json", ".env"); - final Map<String, byte[]> contentWeCareAbout = extractRelevantContent(zip, extensions); + // map that we can process over. These are not huge files so we shouldn't need to worry about memory. + final Map<String, byte[]> contentWeCareAbout = extractRelevantContent(zip); // VTP does not support concurrent executions of the same test with the same associated file name. // It writes files to /tmp and if we were to send two requests with the same file, the results are unpredictable. @@ -891,34 +894,30 @@ public class ExternalTestingManagerImpl implements ExternalTestingManager { * @param zip csar/heat zip to iterate over * @return relevant content from the archive file as a map. */ - private Map<String, byte[]> extractRelevantContent(final byte[] zip, final List<String> extensions) { - final Map<String, byte[]> rv = new HashMap<>(); // FYI, rv = return value. - try (ByteArrayInputStream is = new ByteArrayInputStream(zip)) { - try (ZipInputStream zipStream = new ZipInputStream(is)) { - ZipEntry entry; - while ((entry = zipStream.getNextEntry()) != null) { - final String entryName = entry.getName(); - - // NOTE: leaving this debugging in for dublin... - logger.debug("archive contains entry {}", entryName); - - extractIfMatching(extensions, rv, zipStream, entryName); - } - } - } - catch (IOException ex) { - logger.error("error encountered processing archive", ex); - throw new ExternalTestingException(SDC_RESOLVER_ERR, 500, ex.getMessage()); + private Map<String, byte[]> extractRelevantContent(final byte[] zip) { + final Map<String, byte[]> zipFileAndByteMap; + try { + zipFileAndByteMap = ZipUtils.readZip(zip, false); + } catch (final ZipException ex) { + logger.error("An error occurred while processing archive", ex); + throw new ExternalTestingException(SDC_RESOLVER_ERR, 500, ex.getMessage(), ex); } - return rv; + + return zipFileAndByteMap.entrySet().stream() + .filter(stringEntry -> hasRelevantExtension(stringEntry.getKey())) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); } - private void extractIfMatching(List<String> extensions, Map<String, byte[]> rv, ZipInputStream zipStream, String entryName) throws IOException { - int idx = entryName.lastIndexOf('.'); - if ((idx >= 0) && (extensions.contains(entryName.substring(idx)))) { - byte[] content = IOUtils.toByteArray(zipStream); - rv.put(entryName, content); - } + /** + * Checks if the file matches with a expected extension. + * + * @param filePath the file path + * @return {@code true} if the file extension matches with {@link #relevantArchiveFileExtensionSet}, {@code false} + * otherwise + */ + private boolean hasRelevantExtension(final String filePath) { + final String entryExtension = FilenameUtils.getExtension(filePath); + return StringUtils.isNotEmpty(entryExtension) && (relevantArchiveFileExtensionSet.contains(entryExtension)); } /** diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTest.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTest.java index 04ddf6e2d4..c429709182 100644 --- a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTest.java +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTest.java @@ -18,6 +18,16 @@ package org.openecomp.core.externaltesting.impl; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import java.util.UUID; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.tuple.Pair; @@ -25,28 +35,37 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.*; +import org.mockito.ArgumentMatchers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; -import org.openecomp.core.externaltesting.api.*; +import org.openecomp.core.externaltesting.api.ClientConfiguration; +import org.openecomp.core.externaltesting.api.ExternalTestingManager; +import org.openecomp.core.externaltesting.api.RemoteTestingEndpointDefinition; +import org.openecomp.core.externaltesting.api.TestTreeNode; +import org.openecomp.core.externaltesting.api.VtpNameDescriptionPair; +import org.openecomp.core.externaltesting.api.VtpTestCase; +import org.openecomp.core.externaltesting.api.VtpTestExecutionRequest; +import org.openecomp.core.externaltesting.api.VtpTestExecutionResponse; import org.openecomp.core.externaltesting.errors.ExternalTestingException; import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager; import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager; import org.openecomp.sdc.versioning.VersioningManager; import org.openecomp.sdc.versioning.dao.types.Version; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.RestTemplate; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.*; - @RunWith(MockitoJUnitRunner.class) public class ExternalTestingManagerImplTest { diff --git a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/filedatastructuremodule/CandidateServiceImpl.java b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/filedatastructuremodule/CandidateServiceImpl.java index 3255e186e4..07dc53dfae 100644 --- a/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/filedatastructuremodule/CandidateServiceImpl.java +++ b/openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/services/impl/filedatastructuremodule/CandidateServiceImpl.java @@ -44,6 +44,8 @@ import org.openecomp.sdc.common.errors.ErrorCategory; import org.openecomp.sdc.common.errors.ErrorCode; import org.openecomp.sdc.common.errors.Messages; import org.openecomp.sdc.common.utils.SdcCommon; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipSlipException; import org.openecomp.sdc.datatypes.error.ErrorLevel; import org.openecomp.sdc.datatypes.error.ErrorMessage; import org.openecomp.sdc.heat.datatypes.manifest.FileData; @@ -426,6 +428,11 @@ public class CandidateServiceImpl implements CandidateService { new ByteArrayInputStream(contentData.array()))) { ZipEntry zipEntry; while ((zipEntry = zipStream.getNextEntry()) != null) { + try { + ZipUtils.checkForZipSlipInRead(zipEntry); + } catch (ZipSlipException e) { + throw new IOException(e); + } ZipEntry locZipEntry = new ZipEntry(zipEntry.getName()); zos.putNextEntry(locZipEntry); byte[] buf = new byte[1024]; diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java index 14cf90a272..1bc547aed7 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/impl/ToscaAnalyzerServiceImpl.java @@ -58,6 +58,8 @@ import org.openecomp.core.utilities.file.FileContentHandler; import org.openecomp.core.utilities.file.FileUtils; import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.common.errors.SdcRuntimeException; +import org.openecomp.sdc.common.zip.ZipUtils; +import org.openecomp.sdc.common.zip.exception.ZipSlipException; import org.openecomp.sdc.tosca.datatypes.ToscaElementTypes; import org.openecomp.sdc.tosca.datatypes.ToscaFlatData; import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel; @@ -123,6 +125,7 @@ public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { try (ZipInputStream inputZipStream = new ZipInputStream(new ByteArrayInputStream(toscaCsarPackage))) { ZipEntry zipEntry; while ((zipEntry = inputZipStream.getNextEntry()) != null) { + ZipUtils.checkForZipSlipInRead(zipEntry); byte[] fileContent = FileUtils.toByteArray(inputZipStream); String currentEntryName = zipEntry.getName(); if (!isFile(currentEntryName)) { @@ -141,7 +144,7 @@ public class ToscaAnalyzerServiceImpl implements ToscaAnalyzerService { handleToscaCsarWithoutToscaMetadata(toscaServiceModel); } - } catch (IOException exc) { + } catch (IOException | ZipSlipException exc) { throw new SdcRuntimeException(exc.getMessage(), exc); } return toscaServiceModel; |