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
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 = DocumentBuilderFactory
114 .newInstance().newDocumentBuilder();
115 final Document doc = builder.parse(conn.getInputStream());
116 final XPath xpath = XPathFactory.newInstance().newXPath();
117 final String numFound = xpath.evaluate("/response/result/@numFound", doc);
118 if ("0".equals(numFound)) {
119 missing = true;
120 } else {
121 result = new ArrayList<MavenArtifact>();
122 final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
123 for (int i = 0; i < docs.getLength(); i++) {
124 final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
125 LOGGER.trace("GroupId: {}", g);
126 final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
127 LOGGER.trace("ArtifactId: {}", a);
128 final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
129 NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
130 boolean pomAvailable = false;
131 boolean jarAvailable = false;
132 for (int x = 0; x < atts.getLength(); x++) {
133 final String tmp = xpath.evaluate(".", atts.item(x));
134 if (".pom".equals(tmp)) {
135 pomAvailable = true;
136 } else if (".jar".equals(tmp)) {
137 jarAvailable = true;
138 }
139 }
140
141 atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
142 boolean useHTTPS = false;
143 for (int x = 0; x < atts.getLength(); x++) {
144 final String tmp = xpath.evaluate(".", atts.item(x));
145 if ("https".equals(tmp)) {
146 useHTTPS = true;
147 }
148 }
149 LOGGER.trace("Version: {}", v);
150 result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
151 }
152 }
153 } catch (Throwable e) {
154
155 throw new IOException(e.getMessage(), e);
156 }
157
158 if (missing) {
159 throw new FileNotFoundException("Artifact not found in Central");
160 }
161 } else {
162 LOGGER.debug("Could not connect to Central received response code: {} {}",
163 conn.getResponseCode(), conn.getResponseMessage());
164 throw new IOException("Could not connect to Central");
165 }
166 return result;
167 }
168 }