com.metaeffekt.mirror.index.advisor.MsrcAdvisorIndex 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.index.advisor;
import com.metaeffekt.artifact.analysis.utils.FileUtils;
import com.metaeffekt.artifact.analysis.utils.StringUtils;
import com.metaeffekt.mirror.download.documentation.MirrorMetadata;
import com.metaeffekt.mirror.contents.advisory.MsrcAdvisorEntry;
import com.metaeffekt.mirror.download.advisor.MsrcDownload;
import com.metaeffekt.mirror.download.documentation.DocRelevantMethods;
import com.metaeffekt.mirror.index.Index;
import org.apache.lucene.document.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* The advisories provided in the MSRC download are each almost always linked to at least one CVE, which is also their ID.
* Very rarely however, the ID may be an ADV\d+
identifier, that is not related a specific CVE.
* Some of the AdvisorEntry-related fields such as workarounds, etc. cannot be filled out, as they relate to a specific
* product and are stored in separate fields.
*
* Mapping of JSON content to MsrcAdvisorEntry
fields
*
*
* XML
* MsrcAdvisorEntry
*
*
*
*
* CVE
(with MSRC
prefix)
* id
*
*
* RevisionHistory
> first Revision
> Date
* createDate
*
*
* RevisionHistory
> latest Revision
> Date
* updateDate
*
*
* all CVE-IDs in the note elements
* referenceIds
*
*
* CVSSScoreSets
> each ScoreSet
> Vector
& ProductID
* productCvssVectors
*
*
* Threats
> each Threat
> Type
& Description
& ProductID
* msThreats
*
*
* Remediations
> each Remediation
> multiple tags
* msRemediations
*
*
* ProductStatuses
> each Status
> ProductID
* affectedProducts
*
*
* Title
* summary
*
*
* Notes
> each Note
> (Type
& Title
) & (Text content)
* description
*
*
* Threats
> first Threat
without ProductId
* threat
*
*
*
*/
@MirrorMetadata(directoryName = "msrc-advisors", mavenPropertyName = "msrcAdvisorIndex")
public class MsrcAdvisorIndex extends Index {
private final static Logger LOG = LoggerFactory.getLogger(MsrcAdvisorIndex.class);
public MsrcAdvisorIndex(File baseMirrorDirectory) {
super(baseMirrorDirectory, MsrcAdvisorIndex.class, Collections.singletonList(MsrcDownload.class), Collections.emptyList());
}
@Override
@DocRelevantMethods({"MsrcAdvisorEntry#fromDownloadXml"})
protected Map createIndexDocuments() {
final Map documents = new ConcurrentHashMap<>();
final List files = super.getAllFilesInSubDirectories(super.requiredDownloads[0]);
for (File file : files) {
if (file.getName().endsWith(".xml")) {
super.executor.submit(() -> {
try {
final List lines = FileUtils.readLines(file, StandardCharsets.UTF_8);
if (lines.isEmpty() || lines.size() < 3 && StringUtils.isEmpty(String.join("", lines))) {
return;
}
final org.w3c.dom.Document document = parseXmlDocument(String.join("\n", lines));
final List parsedEntries = MsrcAdvisorEntry.fromDownloadXml(document);
for (MsrcAdvisorEntry entry : parsedEntries) {
if (documents.containsKey(entry.getId())) {
if (StringUtils.isEmpty(entry.getSummary())) {
continue;
}
}
documents.put(entry.getId(), entry.toDocument());
}
} catch (IOException e) {
throw new RuntimeException("Unable to read file contents during indexing: " + file.getAbsolutePath(), e);
} catch (Exception e) {
throw new RuntimeException("Unable to parse file content during indexing: " + file.getAbsolutePath(), e);
}
});
}
}
super.executor.setSize(16);
super.executor.start();
try {
super.executor.join();
} catch (InterruptedException e) {
throw new RuntimeException("Failed to wait for indexing to complete.", e);
}
return documents;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy