com.metaeffekt.mirror.query.NvdCpeApiIndexQuery Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2021-2024 the original author or authors.
*
* Licensed 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.metaeffekt.mirror.query;
import com.metaeffekt.artifact.analysis.utils.StringUtils;
import com.metaeffekt.artifact.analysis.vulnerability.CommonEnumerationUtil;
import com.metaeffekt.mirror.contents.cpe.NvdCpeMetadata;
import com.metaeffekt.mirror.index.IndexSearch;
import com.metaeffekt.mirror.index.nvd.NvdCpeApiIndex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.springett.parsers.cpe.Cpe;
import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class NvdCpeApiIndexQuery extends IndexQuery {
private final static Logger LOG = LoggerFactory.getLogger(NvdCpeApiIndexQuery.class);
public NvdCpeApiIndexQuery(File baseMirrorDirectory) {
super(baseMirrorDirectory, NvdCpeApiIndex.class);
}
public NvdCpeApiIndexQuery(NvdCpeApiIndex index) {
super(index);
}
public List findCpeByVendorProduct(String vendor, String product) {
return sortCpe(findCpeUsingSearcher(new IndexSearch()
.fieldEquals("vendor", vendor)
.fieldEquals("product", product)));
}
public List findCpeByVendorProductVersion(String vendor, String product, String version) {
return sortCpe(findCpeUsingSearcher(new IndexSearch()
.fieldEquals("vendor", vendor)
.fieldEquals("product", product)
.fieldEquals("version", version)));
}
private List sortCpe(Collection cpes) {
if (cpes == null || cpes.isEmpty()) return new ArrayList<>();
try {
return cpes.stream().sorted().collect(Collectors.toList());
} catch (Exception e) {
LOG.warn("Failed to sort CPEs {}: {}" , cpes, e.getMessage());
return new ArrayList<>(cpes);
}
}
public List findCpeByProduct(String product) {
return findCpeUsingSearcher(new IndexSearch().fieldEquals("product", product));
}
public List findCpeByVendor(String vendor) {
return findCpeUsingSearcher(new IndexSearch().fieldEquals("vendor", vendor));
}
public List findCpeByProductFuzzy(String product) {
return findCpeUsingSearcher(new IndexSearch().fieldContains("product", product));
}
public List findCpeByVendorFuzzy(String vendor) {
return findCpeUsingSearcher(new IndexSearch().fieldContains("vendor", vendor));
}
public List findByNvdId(String nvdId) {
return findCpeUsingSearcher(new IndexSearch().fieldEquals("nvdId", nvdId));
}
public List findByCpeUri(String cpeUri) {
return CommonEnumerationUtil.parseCpe(cpeUri)
.map(this::findByCpeUri)
.orElseGet(ArrayList::new);
}
private final static List> CPE_PART_MAPPINGS = Arrays.asList(
s -> s,
s -> s.replace("\\_", "_"),
s -> s.replace("\\.", "."),
s -> s.replace("\\-", "-"),
s -> s.replace("\\/", "/")
);
public List findByCpeUri(Cpe cpeUri) {
for (Function mapper : CPE_PART_MAPPINGS) {
final List cpeList = findByCpeUri(cpeUri, mapper);
if (!cpeList.isEmpty()) {
return cpeList;
}
}
return new ArrayList<>();
}
public List findByCpeUri(Cpe cpeUri, Function partMapper) {
final IndexSearch search = new IndexSearch();
search.fieldEquals("part", cpeUri.getPart().getAbbreviation());
addToSearchIfNotWildcard("vendor", partMapper.apply(cpeUri.getVendor()), search);
addToSearchIfNotWildcard("product", partMapper.apply(cpeUri.getProduct()), search);
addToSearchIfNotWildcard("version", partMapper.apply(cpeUri.getVersion()), search);
addToSearchIfNotWildcard("update", partMapper.apply(cpeUri.getUpdate()), search);
addToSearchIfNotWildcard("edition", partMapper.apply(cpeUri.getEdition()), search);
addToSearchIfNotWildcard("language", partMapper.apply(cpeUri.getLanguage()), search);
addToSearchIfNotWildcard("sw_edition", partMapper.apply(cpeUri.getSwEdition()), search);
addToSearchIfNotWildcard("target_sw", partMapper.apply(cpeUri.getTargetSw()), search);
addToSearchIfNotWildcard("target_hw", partMapper.apply(cpeUri.getTargetHw()), search);
addToSearchIfNotWildcard("other", partMapper.apply(cpeUri.getOther()), search);
return findCpeUsingSearcher(search);
}
private static void addToSearchIfNotWildcard(String key, String value, IndexSearch search) {
if (isNotWildcardPart(value)) {
search.fieldEquals(key, value);
}
}
/**
* A wildcard part is: [, *]
*
* @param part the part to check
* @return true if the part is not a wildcard part
*/
public static boolean isNotWildcardPart(String part) {
if (StringUtils.isEmpty(part)) return false;
return !part.equals("*");
}
private List findCpeUsingSearcher(IndexSearch search) {
return super.index.findDocuments(search).stream()
.map(e -> CommonEnumerationUtil.parseCpe(e.get("cpe23Uri")))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}
public List findCpeMetadataByCpeUri(String cpeUri) {
return CommonEnumerationUtil.parseCpe(cpeUri)
.map(this::findCpeMetadataByCpeUri)
.orElseGet(ArrayList::new);
}
public List findCpeMetadataByCpeUri(Cpe cpeUri) {
for (Function mapper : CPE_PART_MAPPINGS) {
final List metadata = findCpeMetadataByCpeUri(cpeUri, mapper);
if (!metadata.isEmpty()) {
return metadata;
}
}
return new ArrayList<>();
}
public List findCpeMetadataByCpeUri(Cpe cpeUri, Function partMapper) {
final IndexSearch search = new IndexSearch();
search.fieldEquals("part", cpeUri.getPart().getAbbreviation());
addToSearchIfNotWildcard("vendor", partMapper.apply(cpeUri.getVendor()), search);
addToSearchIfNotWildcard("product", partMapper.apply(cpeUri.getProduct()), search);
addToSearchIfNotWildcard("version", partMapper.apply(cpeUri.getVersion()), search);
addToSearchIfNotWildcard("update", partMapper.apply(cpeUri.getUpdate()), search);
addToSearchIfNotWildcard("edition", partMapper.apply(cpeUri.getEdition()), search);
addToSearchIfNotWildcard("language", partMapper.apply(cpeUri.getLanguage()), search);
addToSearchIfNotWildcard("sw_edition", partMapper.apply(cpeUri.getSwEdition()), search);
addToSearchIfNotWildcard("target_sw", partMapper.apply(cpeUri.getTargetSw()), search);
addToSearchIfNotWildcard("target_hw", partMapper.apply(cpeUri.getTargetHw()), search);
addToSearchIfNotWildcard("other", partMapper.apply(cpeUri.getOther()), search);
return findCpeMetadataUsingSearcher(search);
}
private List findCpeMetadataUsingSearcher(IndexSearch search) {
return super.index.findDocuments(search).stream()
.map(NvdCpeMetadata::new)
.collect(Collectors.toList());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy