1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.data.artifactory;
19
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URISyntaxException;
24 import java.net.URL;
25 import java.nio.charset.StandardCharsets;
26 import java.util.List;
27 import java.util.UUID;
28
29 import javax.annotation.concurrent.ThreadSafe;
30
31 import org.apache.hc.core5.http.message.BasicHeader;
32 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
33 import org.owasp.dependencycheck.dependency.Dependency;
34 import org.owasp.dependencycheck.utils.Checksum;
35 import org.owasp.dependencycheck.utils.Downloader;
36 import org.owasp.dependencycheck.utils.ResourceNotFoundException;
37 import org.owasp.dependencycheck.utils.Settings;
38 import org.owasp.dependencycheck.utils.TooManyRequestsException;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42
43
44
45
46
47
48
49
50
51 @ThreadSafe
52 public class ArtifactorySearch {
53
54
55
56
57 private static final Logger LOGGER = LoggerFactory.getLogger(ArtifactorySearch.class);
58
59
60
61
62 private final String rootURL;
63
64
65
66
67 private final boolean allowUsingProxy;
68
69
70
71
72
73
74
75 public ArtifactorySearch(Settings settings) {
76
77 final String searchUrl = settings.getString(Settings.KEYS.ANALYZER_ARTIFACTORY_URL);
78
79 this.rootURL = searchUrl;
80 LOGGER.debug("Artifactory Search URL {}", searchUrl);
81
82 if (null != settings.getString(Settings.KEYS.PROXY_SERVER)) {
83 this.allowUsingProxy = settings.getBoolean(Settings.KEYS.ANALYZER_ARTIFACTORY_USES_PROXY, false);
84 LOGGER.debug("Using proxy configuration? {}", allowUsingProxy);
85 } else {
86 this.allowUsingProxy = settings.getBoolean(Settings.KEYS.ANALYZER_ARTIFACTORY_USES_PROXY, true);
87 LOGGER.debug("Using default non-legacy proxy configuration");
88 }
89
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103 public List<MavenArtifact> search(Dependency dependency) throws IOException {
104
105 final String sha1sum = dependency.getSha1sum();
106 final URL url = buildUrl(sha1sum);
107 final StringBuilder msg = new StringBuilder("Could not connect to Artifactory at")
108 .append(url);
109 try {
110 final BasicHeader artifactoryResultDetail = new BasicHeader("X-Result-Detail", "info");
111 return Downloader.getInstance().fetchAndHandle(url, new ArtifactorySearchResponseHandler(dependency), List.of(artifactoryResultDetail),
112 allowUsingProxy);
113 } catch (TooManyRequestsException e) {
114 throw new IOException(msg.append(" (429): Too manu requests").toString(), e);
115 } catch (URISyntaxException e) {
116 throw new IOException(msg.append(" (400): Invalid URL").toString(), e);
117 } catch (ResourceNotFoundException e) {
118 throw new IOException(msg.append(" (404): Not found").toString(), e);
119 }
120 }
121
122
123
124
125
126
127
128
129 private URL buildUrl(String sha1sum) throws MalformedURLException {
130
131
132 return new URL(rootURL + "/api/search/checksum?sha1=" + sha1sum);
133 }
134
135
136
137
138
139
140
141
142 public boolean preflightRequest() {
143 URL url = null;
144 try {
145 url = buildUrl(Checksum.getSHA1Checksum(UUID.randomUUID().toString()));
146 Downloader.getInstance().fetchContent(url, StandardCharsets.UTF_8);
147 return true;
148 } catch (IOException e) {
149 LOGGER.error("Cannot connect to Artifactory", e);
150 return false;
151 } catch (TooManyRequestsException e) {
152 LOGGER.warn("Expected 200 result from Artifactory ({}), got 429", url);
153 return false;
154 } catch (ResourceNotFoundException e) {
155 LOGGER.warn("Expected 200 result from Artifactory ({}), got 404", url);
156 return false;
157 }
158
159 }
160 }