1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.data.central;
19
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.net.HttpURLConnection;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.List;
26 import javax.xml.parsers.DocumentBuilder;
27 import javax.xml.xpath.XPath;
28 import javax.xml.xpath.XPathConstants;
29 import javax.xml.xpath.XPathFactory;
30 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
31 import org.owasp.dependencycheck.utils.Settings;
32 import org.owasp.dependencycheck.utils.URLConnectionFactory;
33 import org.owasp.dependencycheck.utils.XmlUtils;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.w3c.dom.Document;
37 import org.w3c.dom.NodeList;
38
39
40
41
42
43
44 public class CentralSearch {
45
46
47
48
49 private final URL rootURL;
50
51
52
53
54 private final boolean useProxy;
55
56
57
58
59 private static final Logger LOGGER = LoggerFactory.getLogger(CentralSearch.class);
60
61
62
63
64
65
66
67 public CentralSearch(URL rootURL) {
68 this.rootURL = rootURL;
69 if (null != Settings.getString(Settings.KEYS.PROXY_SERVER)) {
70 useProxy = true;
71 LOGGER.debug("Using proxy");
72 } else {
73 useProxy = false;
74 LOGGER.debug("Not using proxy");
75 }
76 }
77
78
79
80
81
82
83
84
85
86
87
88 public List<MavenArtifact> searchSha1(String sha1) throws IOException {
89 if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
90 throw new IllegalArgumentException("Invalid SHA1 format");
91 }
92 List<MavenArtifact> result = null;
93 final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
94
95 LOGGER.debug("Searching Central url {}", url);
96
97
98
99
100
101 final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
102
103 conn.setDoOutput(true);
104
105
106
107 conn.addRequestProperty("Accept", "application/xml");
108 conn.connect();
109
110 if (conn.getResponseCode() == 200) {
111 boolean missing = false;
112 try {
113 final DocumentBuilder builder = XmlUtils.buildSecureDocumentBuilder();
114 final Document doc = builder.parse(conn.getInputStream());
115 final XPath xpath = XPathFactory.newInstance().newXPath();
116 final String numFound = xpath.evaluate("/response/result/@numFound", doc);
117 if ("0".equals(numFound)) {
118 missing = true;
119 } else {
120 result = new ArrayList<MavenArtifact>();
121 final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
122 for (int i = 0; i < docs.getLength(); i++) {
123 final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
124 LOGGER.trace("GroupId: {}", g);
125 final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
126 LOGGER.trace("ArtifactId: {}", a);
127 final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
128 NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
129 boolean pomAvailable = false;
130 boolean jarAvailable = false;
131 for (int x = 0; x < atts.getLength(); x++) {
132 final String tmp = xpath.evaluate(".", atts.item(x));
133 if (".pom".equals(tmp)) {
134 pomAvailable = true;
135 } else if (".jar".equals(tmp)) {
136 jarAvailable = true;
137 }
138 }
139
140 atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
141 boolean useHTTPS = false;
142 for (int x = 0; x < atts.getLength(); x++) {
143 final String tmp = xpath.evaluate(".", atts.item(x));
144 if ("https".equals(tmp)) {
145 useHTTPS = true;
146 }
147 }
148 LOGGER.trace("Version: {}", v);
149 result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
150 }
151 }
152 } catch (Throwable e) {
153
154 throw new IOException(e.getMessage(), e);
155 }
156
157 if (missing) {
158 throw new FileNotFoundException("Artifact not found in Central");
159 }
160 } else {
161 LOGGER.debug("Could not connect to Central received response code: {} {}",
162 conn.getResponseCode(), conn.getResponseMessage());
163 throw new IOException("Could not connect to Central");
164 }
165 return result;
166 }
167 }