Initial commit

This commit is contained in:
Šesták Vít
2020-01-31 15:12:34 +01:00
commit 12378b0505
15 changed files with 807 additions and 0 deletions

19
.gitignore vendored Normal file
View File

@@ -0,0 +1,19 @@
# Created by .ignore support plugin (hsz.mobi)
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
!/.mvn/wrapper/maven-wrapper.jar
.idea
sample
*.iml

17
README.md Normal file
View File

@@ -0,0 +1,17 @@
A plugin for OWASP Dependency Check that analyzes IPK files from YOCTO.
Useful for finding known vulnerabilities and licenses.
The plugin automatically suppresses CVEs mentioned in source section, as it expects any mention of a CVE in this section is a patch fixing the CVE.
## Requirements
This plugin calls `tar` and `ar` utilities. You need them on $PATH.
Tested with Debian, but it will likely work with other distributions or even with Windows if these two utilities are on $PATH (or %PATH% :) ).
## Howto
1. Build JAR file using `mvn package`.
2. Add the JAR file to `plugins` directory of OWASP Dependency Check (CLI version).
3. Run the ODC on IPK files with com.ysoft.yocto.enabled=true.

49
pom.xml Normal file
View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ysoft.security</groupId>
<artifactId>odc-yocto-analyzer</artifactId>
<version>1.2.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-core</artifactId>
<version>5.2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,182 @@
package com.ysoft.security.odc.yocto;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.owasp.dependencycheck.analyzer.AbstractFileTypeAnalyzer;
import org.owasp.dependencycheck.utils.InvalidSettingException;
import org.owasp.dependencycheck.utils.Settings;
import static com.ysoft.security.odc.yocto.ControlFileParser.parseControlFile;
abstract class AbstractYoctoAnalyzer extends AbstractFileTypeAnalyzer {
public static final String YOCTO_ANALYZER_KEY = "com.ysoft.yocto.enabled";
public static final String YOCTO_ANALYZER_EXPERIMENTAL_DEBIAN_KEY = "com.ysoft.yocto.experimental.debian.enabled";
public static final String IPK_SOURCE = "ipk";
protected FileFilter getFileFilter() {
return f -> {
final String name = f.getName().toLowerCase();
return name.endsWith(".ipk") || (isExperimentalDebEnabled() && name.endsWith(".deb"));
};
}
@Override
protected String getAnalyzerEnabledSettingKey() {
return YOCTO_ANALYZER_KEY;
}
private void throwChecked(Throwable e) {
this.throwChecked0(e);
}
protected boolean isExperimentalDebEnabled() {
return getSettings().getBoolean(YOCTO_ANALYZER_EXPERIMENTAL_DEBIAN_KEY, false);
}
@SuppressWarnings("unchecked")
private <T extends RuntimeException> void throwChecked0(Throwable e) {
throw (T) e;
}
// In future, we might want to be more universal: https://blog.philippklaus.de/2011/04/have-a-look-into-an-ipk-file-used-by-the-ipkg-or-opkg-manager
protected IpkFile parseIpkFile(File ipkFile) throws IOException {
return new IpkFile(parseIpkManifest(ipkFile));//listIpkFiles(ipkFile));
}
private Set<String> listIpkFiles(File ipkFile) throws IOException {
// TODO: add support for xz, bz etc.
final Process arProcess = createArExtractionProcess(ipkFile.getAbsolutePath(), "data.tar.gz");
try{
final Future<String> arStderrFuture = processStream(arProcess.getErrorStream());
final Process tarProcess = new ProcessBuilder("tar", "-tz").start();
try {
final Future<String> tarStderrFuture = processStream(tarProcess.getErrorStream());
final Future<Void> copyResult = pipe(arProcess.getInputStream(), tarProcess.getOutputStream());
final Set<String> fileNames = new HashSet<>();
try(final BufferedReader reader = new BufferedReader(new InputStreamReader(tarProcess.getInputStream()))){
String line;
while((line = reader.readLine()) != null){
fileNames.add(line);
}
}
copyResult.get(); // this throws exception if pipe has failed
final int tarReturnCode = tarProcess.waitFor();
final int arReturnCode = arProcess.waitFor();
checkStderr(tarStderrFuture, "tar");
checkStderr(arStderrFuture, "ar");
if (tarReturnCode != 0 || arReturnCode != 0) {
throw new IOException("Bad return code (tar: " + tarReturnCode + ", ar: " + arReturnCode + ")");
}
return fileNames;
} catch (InterruptedException | ExecutionException e) {
throw new IOException(e);
} finally {
tarProcess.destroyForcibly();
}
}finally{
arProcess.destroyForcibly();
}
}
private IpkManifest parseIpkManifest(File ipkFile) throws IOException {
final Process arProcess = createArExtractionProcess(ipkFile.getAbsolutePath(), "control.tar.gz");
try{
final Future<String> arStderrFuture = processStream(arProcess.getErrorStream());
final Process tarProcess = new ProcessBuilder("tar", "-xzO", "./control").start();
try{
final Future<String> tarStderrFuture = processStream(tarProcess.getErrorStream());
final Future<Void> copyResult = pipe(arProcess.getInputStream(), tarProcess.getOutputStream());
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
final byte[] buff = new byte[1024];
while((len = tarProcess.getInputStream().read(buff)) != -1){
baos.write(buff, 0, len);
}
copyResult.get(); // this throws exception if pipe has failed
final int tarReturnCode = tarProcess.waitFor();
final int arReturnCode = arProcess.waitFor();
checkStderr(tarStderrFuture, "tar");
checkStderr(arStderrFuture, "ar");
if(tarReturnCode != 0 || arReturnCode != 0){
throw new IOException("Bad return code (tar: "+tarReturnCode+", ar: "+arReturnCode+")");
}
return new IpkManifest(parseControlFile(baos.toString("utf-8")));
} catch (InterruptedException | ExecutionException e) {
throw new IOException(e);
} finally {
tarProcess.destroyForcibly();
}
}finally{
arProcess.destroyForcibly();
}
}
private Process createArExtractionProcess(String arPath, String file) throws IOException {
return new ProcessBuilder("ar", "p", "--", arPath, file).start();
}
private void checkStderr(Future<String> stderrFuture, String name) throws ExecutionException, InterruptedException, IOException {
final String result = stderrFuture.get();
if(!result.equals("")){
throw new IOException("Process "+name+" has written something to stderr: "+result);
}
}
private Future<String> processStream(InputStream inputStream) {
final ExecutorService executor = Executors.newSingleThreadExecutor();
try {
return executor.submit(() -> {
final InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
final char[] buff = new char[1024];
int len;
final StringBuilder out = new StringBuilder();
while ((len = reader.read(buff)) != -1){
out.append(buff, 0, len);
}
return out.toString();
});
}finally {
executor.shutdown();
}
}
protected Future<Void> pipe(InputStream in, OutputStream out){
final ExecutorService executor = Executors.newSingleThreadExecutor();
try{
return executor.submit(() -> {
int len;
final byte[] buff = new byte[1024];
try {
while ((len = in.read(buff)) != -1) {
out.write(buff, 0, len);
}
out.close();
} catch (IOException e){
throwChecked(e);
}
return null;
});
}finally {
executor.shutdown();
}
}
}

View File

@@ -0,0 +1,110 @@
package com.ysoft.security.odc.yocto;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class ControlFileLineBuilder{
private final List<String> lines = new ArrayList<>();
private final Key key;
public ControlFileLineBuilder(String line) throws IOException {
final int pos = line.indexOf(':');
if(pos == -1){
throw new IOException("Bad line: expected colon: "+line);
}
key = new Key(line.substring(0, pos));
addLine(line.substring(pos+1));
}
private void addLine(String s) {
lines.add(s.trim());
}
public Line build() {
return new Line(key, lines.stream().collect(Collectors.joining("\n")));
}
public void add(String line) {
addLine(line);
}
}
class Line{
private final Key key;
private final String value;
public Line(Key key, String value) {
this.key = key;
this.value = value;
}
public Key getKey() {
return key;
}
public String getValue() {
return value;
}
}
class ControlFileParagraphBuilder{
private ControlFileLineBuilder lineBuilder;
private Map<Key, String> map = new HashMap<>();
public void addLine(String line) throws IOException {
if(line.startsWith(" ") || line.startsWith("\t")){
if(lineBuilder == null) {
throw new IOException("Bad control file: paragraph cannot start with whitespace.");
} else {
lineBuilder.add(line);
}
}else{
finishCurrentLine();
lineBuilder = new ControlFileLineBuilder(line);
}
}
private void finishCurrentLine() throws IOException {
if(lineBuilder != null){
add(lineBuilder.build());
lineBuilder = null;
}
}
private void add(Line line) throws IOException {
if(map.containsKey(line.getKey())){
throw new IOException("Duplicate key: "+line.getKey());
}
map.put(line.getKey(), line.getValue());
}
public Map<Key, String> build() throws IOException {
finishCurrentLine();
final Map<Key, String> res = Collections.unmodifiableMap(map);
map = null; // don't allow reuse
return res;
}
}
public class ControlFileParser {
/**
* Works according specification https://www.debian.org/doc/debian-policy/ch-controlfields.html with some limitations:
* * parses only one paragraph
* @param s
* @return
*/
public static Map<Key, String> parseControlFile(String s) throws IOException {
final ControlFileParagraphBuilder builder = new ControlFileParagraphBuilder();
for(final String line : s.split("\n")){
builder.addLine(line);
}
return builder.build();
}
}

View File

@@ -0,0 +1,67 @@
package com.ysoft.security.odc.yocto;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class IpkFile {
private final IpkManifest manifest;
//private final Set<String> fileNames;
public IpkFile(IpkManifest manifest/*, Set<String> fileNames*/) {
this.manifest = manifest;
//this.fileNames = fileNames;
}
public IpkManifest getManifest() {
return manifest;
}
/*public Set<String> getFileNames() {
return fileNames;
}*/
public Set<String> getFixedCves() {
return manifest.getFixedCves();
}
public String getPackageName(){
return manifest.get(IpkManifest.KEY_PACKAGE);
}
public String getVersion(){
return manifest.get(IpkManifest.KEY_VERSION);
}
public String getDescription(){
return manifest.get(IpkManifest.KEY_DESCRIPTION);
}
public String getLicense(){
return manifest.get(IpkManifest.KEY_LICENSE);
}
public String getHomepage(){
return manifest.get(IpkManifest.KEY_HOMEPAGE);
}
public String getOE(){
return manifest.get(IpkManifest.KEY_OE);
}
public List<String> getSources(boolean experimentalDebEnabled){
final String source = experimentalDebEnabled
? manifest.get(IpkManifest.KEY_SOURCE, "")
: manifest.get(IpkManifest.KEY_SOURCE);
return Arrays.asList(source.split("\\s+"));
}
@Override
public String toString() {
return "IpkFile{" +
"manifest=" + manifest +
//", fileNames=" + fileNames +
'}';
}
}

View File

@@ -0,0 +1,50 @@
package com.ysoft.security.odc.yocto;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IpkManifest {
public static final Key KEY_PACKAGE = new Key("Package");
public static final Key KEY_VERSION = new Key("Version");
public static final Key KEY_DESCRIPTION = new Key("Description");
public static final Key KEY_LICENSE = new Key("License");
public static final Key KEY_HOMEPAGE = new Key("Homepage");
public static final Key KEY_SOURCE = new Key("Source");
public static final Key KEY_OE = new Key("OE");
private static final Pattern CVE_REGEX = Pattern.compile("CVE-[0-9]{4}-[0-9]{4,}"); // slightly more permissible than https://cve.mitre.org/cve/identifiers/syntaxchange.html (leading zeros, number length)
private final Map<Key, String> manifest;
public IpkManifest(Map<Key, String> manifest) {
this.manifest = manifest;
}
public String get(Key key){
return manifest.get(key);
}
public String get(Key key, String defaultValue){
return manifest.getOrDefault(key, defaultValue);
}
public Set<String> getFixedCves() {
final Matcher matcher = CVE_REGEX.matcher(manifest.getOrDefault(KEY_SOURCE, ""));
final Set<String> set = new HashSet<>();
while(matcher.find()){
set.add(matcher.group());
}
return Collections.unmodifiableSet(set);
}
@Override
public String toString() {
return "IpkManifest{" +
"manifest=" + manifest +
'}';
}
}

View File

@@ -0,0 +1,40 @@
package com.ysoft.security.odc.yocto;
public class Key{
private final String key;
private final String canonicalKey;
public Key(String key) {
this.key = key;
this.canonicalKey = key.toLowerCase();
}
public String getKey() {
return key;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Key key = (Key) o;
return canonicalKey.equals(key.canonicalKey);
}
@Override
public int hashCode() {
return canonicalKey.hashCode();
}
@Override
public String toString() {
return "Key(" + key + ")";
}
}

View File

@@ -0,0 +1,63 @@
package com.ysoft.security.odc.yocto;
import com.github.packageurl.MalformedPackageURLException;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.naming.PurlIdentifier;
import org.owasp.dependencycheck.exception.InitializationException;
import java.io.IOException;
import java.util.List;
import static org.owasp.dependencycheck.dependency.EvidenceType.*;
public class YoctoAnalyzer extends AbstractYoctoAnalyzer {
public AnalysisPhase getAnalysisPhase() {
return AnalysisPhase.INFORMATION_COLLECTION;
}
@Override
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {}
public String getName() {
return "YOCTO analyzer";
}
@Override
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
try {
final IpkFile ipkFile = parseIpkFile(dependency.getActualFile());
dependency.addSoftwareIdentifier(new PurlIdentifier("yocto", ipkFile.getPackageName(), ipkFile.getVersion(), Confidence.HIGHEST));
dependency.addEvidence(PRODUCT, IPK_SOURCE, "package name", ipkFile.getPackageName(), Confidence.HIGHEST);
dependency.addEvidence(VENDOR, IPK_SOURCE, "package name", ipkFile.getPackageName()+"_project", Confidence.LOW);
final String oe = ipkFile.getOE();
final List<String> sources = ipkFile.getSources(isExperimentalDebEnabled());
if(!sources.isEmpty()){
dependency.addEvidence(VENDOR, IPK_SOURCE, "source url", sources.get(0), Confidence.MEDIUM);
//productEvidence.addEvidence(IPK_SOURCE, "source url", sources.get(0), Confidence.MEDIUM);
}
if(oe != null){
dependency.addEvidence(PRODUCT, IPK_SOURCE, "name", oe, Confidence.HIGHEST);
dependency.addEvidence(VENDOR, IPK_SOURCE, "name", oe+"_project", Confidence.LOW);
}
dependency.addEvidence(VERSION, IPK_SOURCE, "package version", ipkFile.getVersion(), Confidence.HIGH);
dependency.addEvidence(VERSION, IPK_SOURCE, "version", ipkFile.getVersion().replaceAll("-r[0-9]+$", ""), Confidence.HIGHEST);
final String homepage = ipkFile.getHomepage();
dependency.setDescription(ipkFile.getDescription());
dependency.setLicense(ipkFile.getLicense());
if(homepage != null && !homepage.equals("")) {
dependency.addEvidence(VENDOR, IPK_SOURCE, "organization url", homepage, Confidence.HIGHEST);
dependency.addEvidence(PRODUCT, IPK_SOURCE, "organization url", homepage, Confidence.HIGHEST);
}
} catch (IOException | MalformedPackageURLException e) {
throw new AnalysisException(e);
}
}
}

View File

@@ -0,0 +1,45 @@
package com.ysoft.security.odc.yocto;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.AbstractAnalyzer;
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.EvidenceType;
import static org.owasp.dependencycheck.dependency.EvidenceType.*;
/**
* FileNameAnalyzer tries to get the version from file name. The problem is that it includes “-r0” or something similar from distribution, which is not
* much relevant for ODC. This analyzer removes the version added by FileNameAnalyzer if YOCTO analyzer has added some version evidence.
*/
public class YoctoFilenameVersionSuppressionAnalyzer extends AbstractAnalyzer {
@Override
protected String getAnalyzerEnabledSettingKey() {
return AbstractYoctoAnalyzer.YOCTO_ANALYZER_KEY;
}
@Override
public String getName() {
return "YOCTO filename version suppression";
}
@Override
public AnalysisPhase getAnalysisPhase() {
return AnalysisPhase.POST_INFORMATION_COLLECTION;
}
@Override
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
cleanEvidence(dependency, VERSION);
cleanEvidence(dependency, PRODUCT);
cleanEvidence(dependency, VENDOR);
}
private static void cleanEvidence(Dependency dependency, EvidenceType evidenceType) {
if(dependency.getEvidence(evidenceType).stream().anyMatch(x -> x.getSource().equals(AbstractYoctoAnalyzer.IPK_SOURCE))){
dependency.getEvidence(evidenceType).stream().filter(item -> item.getSource().equals("file")).forEach(evidence -> dependency.removeEvidence(evidenceType, evidence));
}
}
}

View File

@@ -0,0 +1,54 @@
package com.ysoft.security.odc.yocto;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.AnalysisPhase;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.exception.InitializationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class YoctoPatchedVulnerabilitySuppressionAnalyzer extends AbstractYoctoAnalyzer {
private static final Logger LOGGER = LoggerFactory.getLogger(YoctoPatchedVulnerabilitySuppressionAnalyzer.class);
@Override
public String getName() {
return "YOCTO suppression analyzer";
}
@Override
protected void prepareFileTypeAnalyzer(Engine engine) throws InitializationException {}
@Override
public AnalysisPhase getAnalysisPhase() {
return AnalysisPhase.POST_FINDING_ANALYSIS;
}
@Override
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
try{
final IpkFile ipkFile = parseIpkFile(dependency.getActualFile());
final Set<String> remainingCvesForSuppression = new HashSet<>(ipkFile.getFixedCves());
for (final Vulnerability vulnerability : new HashSet<>(dependency.getVulnerabilities())) { // For some reason, this API does not return a copy, which causes ConcurrentModificationException.
final String vulnerabilityName = vulnerability.getName();
if (remainingCvesForSuppression.contains(vulnerabilityName)) {
dependency.removeVulnerability(vulnerability);
dependency.addSuppressedVulnerability(vulnerability);
remainingCvesForSuppression.remove(vulnerabilityName);
}
}
if(!remainingCvesForSuppression.isEmpty()){
LOGGER.warn("Dependency {} has some undetected vulnerabilities to suppress that were not matched: {}", dependency.getActualFilePath(), remainingCvesForSuppression);
}
} catch (IOException e) {
throw new AnalysisException(e);
}
}
}

View File

@@ -0,0 +1,3 @@
com.ysoft.security.odc.yocto.YoctoAnalyzer
com.ysoft.security.odc.yocto.YoctoPatchedVulnerabilitySuppressionAnalyzer
com.ysoft.security.odc.yocto.YoctoFilenameVersionSuppressionAnalyzer

View File

@@ -0,0 +1,40 @@
package com.ysoft.security.odc.yocto;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ControlFileParserTest {
@Test
public void parseControlFile() throws IOException {
try(final InputStream in = getClass().getResourceAsStream("/example.control")) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final byte[] buff = new byte[1024];
int len;
while((len = in.read(buff)) != -1){
baos.write(buff, 0, len);
}
final String s = baos.toString("utf-8");
final Map<Key, String> res = ControlFileParser.parseControlFile(s);
// single-line
assertEquals(res.get(new Key("Package")), "augeas-lenses");
// case sensitivity
assertEquals(res.get(new Key("packAge")), "augeas-lenses");
// missint
assertEquals(res.get(new Key("hackage")), null);
// multiline
assertEquals(res.get(new Key("Description")), "Augeas configuration API\n" + "Augeas configuration API.");
// last line
assertEquals(res.get(new Key("Source")), "http://download.augeas.net/augeas-1.4.0.tar.gz file://add-missing-argz-conditional"
+ ".patch file://sepbuildfix.patch file://0001-Unset-need_charset_alias-when-building-for-musl.patch");
}
}
}

View File

@@ -0,0 +1,56 @@
package com.ysoft.security.odc.yocto;
import org.junit.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import static org.junit.Assert.*;
public class IpkManifestTest {
@Test
public void testCveParseXinetd(){
final IpkManifest ipkManifest = new IpkManifest(ImmutableMap.of(new Key("Source"), "git://github.com/xinetd-org/xinetd.git;protocol=https "
+ "file://xinetd.init file://xinetd.conf file://xinetd.default file://Various-fixes-from-the-previous-maintainer.patch "
+ "file://Disable-services-from-inetd.conf-if-a-service-with-t.patch file://xinetd-should-be-able-to-listen-on-IPv6-even-in-ine.patch "
+ "file://xinetd-CVE-2013-4342.patch file://xinetd.service"));
assertEquals(ImmutableSet.of("CVE-2013-4342"), ipkManifest.getFixedCves());
}
@Test
public void testCveParseOpenSsh(){
final IpkManifest ipkManifest = new IpkManifest(ImmutableMap.of(new Key("Source"), "Source: ftp://ftp.openbsd"
+ ".org/pub/OpenBSD/OpenSSH/portable/openssh-7.1p2.tar.gz file://sshd_config file://ssh_config file://init file://sshd file://sshd"
+ ".socket file://sshd@.service file://sshdgenkeys.service file://volatiles.99_sshd file://add-test-support-for-busybox.patch "
+ "file://run-ptest file://CVE-2016-1907_upstream_commit.patch file://CVE-2016-1907_2.patch file://CVE-2016-1907_3.patch "
+ "file://CVE-2016-3115.patch file://sshdgenkeys.service\n"
+ "/home/user/projects/odc-yocto-analyzer/sample/cortexa9t2hf-vfp-neon/openssh-ssh_7.1p2-r0_cortexa9t2hf-vfp-neon.ipk"));
assertEquals(ImmutableSet.of("CVE-2016-1907", "CVE-2016-1907", "CVE-2016-1907", "CVE-2016-3115"), ipkManifest.getFixedCves());
}
@Test
public void testCveParseLibXml2(){
final IpkManifest ipkManifest = new IpkManifest(ImmutableMap.of(new Key("Source"), "Source: ftp://xmlsoft.org/libxml2/libxml2-2.9.2.tar.gz;"
+ "name=libtar file://libxml-64bit.patch file://ansidecl.patch file://runtest.patch file://run-ptest file://libxml2-CVE-2014-0191-fix"
+ ".patch file://python-sitepackages-dir.patch file://libxml-m4-use-pkgconfig.patch file://configure.ac-fix-cross-compiling-warning"
+ ".patch file://0001-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch "
+ "file://CVE-2015-7941-1-Stop-parsing-on-entities-boundaries-errors.patch "
+ "file://CVE-2015-7941-2-Cleanup-conditional-section-error-handling.patch "
+ "file://CVE-2015-8317-Fail-parsing-early-on-if-encoding-conversion-failed.patch "
+ "file://CVE-2015-7942-Another-variation-of-overflow-in-Conditional-section.patch "
+ "file://CVE-2015-7942-2-Fix-an-error-in-previous-Conditional-section-patch.patch "
+ "file://0001-CVE-2015-8035-Fix-XZ-compression-support-loop.patch "
+ "file://CVE-2015-7498-Avoid-processing-entities-after-encoding-conversion-.patch "
+ "file://0001-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch file://CVE-2015-7499-1-Add-xmlHaltParser-to-stop-the-parser"
+ ".patch file://CVE-2015-7499-2-Detect-incoherency-on-GROW.patch file://0001-Fix-a-bug-on-name-parsing-at-the-end-of-current-inpu"
+ ".patch file://0001-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch "
+ "file://0001-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch file://0001-CVE-2015-5312-Another-entity-expansion-issue"
+ ".patch file://CVE-2015-8241.patch file://CVE-2015-8710.patch http://www.w3.org/XML/Test/xmlts20080827.tar.gz;name=testtar "
+ "file://72a46a519ce7326d9a00f0b6a7f2a8e958cd1675.patch file://0001-threads-Define-pthread-definitions-for-glibc-complia.patch"));
assertEquals(ImmutableSet.of("CVE-2014-0191", "CVE-2015-1819", "CVE-2015-7941", "CVE-2015-8317", "CVE-2015-7942", "CVE-2015-8035",
"CVE-2015-7498", "CVE-2015-7497", "CVE-2015-7499", "CVE-2015-7499", "CVE-2015-7500", "CVE-2015-8242", "CVE-2015-5312",
"CVE-2015-8241", "CVE-2015-8710"), ipkManifest.getFixedCves());
}
}

View File

@@ -0,0 +1,12 @@
Package: augeas-lenses
Version: 1.4.0-r0
Description: Augeas configuration API
Augeas configuration API.
Section: base
Priority: optional
Maintainer: OE-Core Developers <openembedded-core@lists.openembedded.org>
License: LGPLv2.1+
Architecture: cortexa9t2hf-vfp-neon
OE: augeas
Homepage: http://augeas.net/
Source: http://download.augeas.net/augeas-1.4.0.tar.gz file://add-missing-argz-conditional.patch file://sepbuildfix.patch file://0001-Unset-need_charset_alias-when-building-for-musl.patch