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.parsers.DocumentBuilderFactory;
28 import javax.xml.xpath.XPath;
29 import javax.xml.xpath.XPathConstants;
30 import javax.xml.xpath.XPathFactory;
31 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
32 import org.owasp.dependencycheck.utils.Settings;
33 import org.owasp.dependencycheck.utils.URLConnectionFactory;
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 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 public List<MavenArtifact> searchSha1(String sha1) throws IOException {
87 if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) {
88 throw new IllegalArgumentException("Invalid SHA1 format");
89 }
90
91 final URL url = new URL(rootURL + String.format("?q=1:\"%s\"&wt=xml", sha1));
92
93 LOGGER.debug("Searching Central url {}", url);
94
95
96
97
98
99 final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
100
101 conn.setDoOutput(true);
102
103
104
105 conn.addRequestProperty("Accept", "application/xml");
106 conn.connect();
107
108 if (conn.getResponseCode() == 200) {
109 boolean missing = false;
110 try {
111 final DocumentBuilder builder = DocumentBuilderFactory
112 .newInstance().newDocumentBuilder();
113 final Document doc = builder.parse(conn.getInputStream());
114 final XPath xpath = XPathFactory.newInstance().newXPath();
115 final String numFound = xpath.evaluate("/response/result/@numFound", doc);
116 if ("0".equals(numFound)) {
117 missing = true;
118 } else {
119 final List<MavenArtifact> result = new ArrayList<MavenArtifact>();
120 final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
121 for (int i = 0; i < docs.getLength(); i++) {
122 final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
123 LOGGER.trace("GroupId: {}", g);
124 final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
125 LOGGER.trace("ArtifactId: {}", a);
126 final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
127 NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
128 boolean pomAvailable = false;
129 boolean jarAvailable = false;
130 for (int x = 0; x < atts.getLength(); x++) {
131 final String tmp = xpath.evaluate(".", atts.item(x));
132 if (".pom".equals(tmp)) {
133 pomAvailable = true;
134 } else if (".jar".equals(tmp)) {
135 jarAvailable = true;
136 }
137 }
138
139 atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
140 boolean useHTTPS = false;
141 for (int x = 0; x < atts.getLength(); x++) {
142 final String tmp = xpath.evaluate(".", atts.item(x));
143 if ("https".equals(tmp)) {
144 useHTTPS = true;
145 }
146 }
147
148 LOGGER.trace("Version: {}", v);
149 result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
150 }
151
152 return result;
153 }
154 } catch (Throwable e) {
155
156
157 throw new IOException(e.getMessage(), e);
158 }
159
160 if (missing) {
161 throw new FileNotFoundException("Artifact not found in Central");
162 }
163 } else {
164 LOGGER.debug("Could not connect to Central received response code: {} {}",
165 conn.getResponseCode(), conn.getResponseMessage());
166 throw new IOException("Could not connect to Central");
167 }
168
169 return null;
170 }
171 }