1 package com.jsql.util;
2
3 import com.jsql.model.InjectionModel;
4 import com.jsql.model.bean.util.Header;
5 import com.jsql.model.bean.util.Interaction;
6 import com.jsql.model.bean.util.Request;
7 import com.jsql.model.exception.InjectionFailureException;
8 import com.jsql.model.exception.JSqlException;
9 import com.jsql.model.injection.method.AbstractMethodInjection;
10 import org.apache.commons.lang3.StringUtils;
11 import org.apache.logging.log4j.LogManager;
12 import org.apache.logging.log4j.Logger;
13
14 import java.io.IOException;
15 import java.net.Authenticator;
16 import java.net.CookieManager;
17 import java.net.PasswordAuthentication;
18 import java.net.URI;
19 import java.net.http.HttpClient;
20 import java.net.http.HttpClient.Version;
21 import java.net.http.HttpHeaders;
22 import java.net.http.HttpRequest;
23 import java.net.http.HttpRequest.BodyPublishers;
24 import java.net.http.HttpRequest.Builder;
25 import java.net.http.HttpResponse;
26 import java.net.http.HttpResponse.BodyHandlers;
27 import java.security.SecureRandom;
28 import java.time.Duration;
29 import java.util.*;
30 import java.util.AbstractMap.SimpleEntry;
31 import java.util.Map.Entry;
32 import java.util.stream.Collectors;
33 import java.util.stream.Stream;
34
35
36
37
38
39 public class ConnectionUtil {
40
41 private static final Logger LOGGER = LogManager.getRootLogger();
42
43 private String urlByUser;
44 private String urlBase;
45 private AbstractMethodInjection methodInjection;
46 private String typeRequest = StringUtil.GET;
47 private final Random randomForUserAgent = new SecureRandom();
48 private final InjectionModel injectionModel;
49 private final CookieManager cookieManager = new CookieManager();
50
51 public ConnectionUtil(InjectionModel injectionModel) {
52 this.injectionModel = injectionModel;
53 }
54
55 public HttpClient.Builder getHttpClient() {
56 var httpClientBuilder = HttpClient.newBuilder()
57 .connectTimeout(Duration.ofSeconds(this.getTimeout()))
58 .sslContext(this.injectionModel.getMediatorUtils().getCertificateUtil().getSslContext())
59 .followRedirects(
60 this.injectionModel.getMediatorUtils().getPreferencesUtil().isFollowingRedirection()
61 ? HttpClient.Redirect.ALWAYS
62 : HttpClient.Redirect.NEVER
63 );
64 if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isHttp2Disabled()) {
65 httpClientBuilder.version(Version.HTTP_1_1);
66 }
67 if (!this.injectionModel.getMediatorUtils().getPreferencesUtil().isNotProcessingCookies()) {
68 httpClientBuilder.cookieHandler(this.cookieManager);
69 }
70 if (this.injectionModel.getMediatorUtils().getAuthenticationUtil().isAuthentEnabled()) {
71 httpClientBuilder.authenticator(new Authenticator() {
72 @Override
73 protected PasswordAuthentication getPasswordAuthentication() {
74 return new PasswordAuthentication(
75 ConnectionUtil.this.injectionModel.getMediatorUtils().getAuthenticationUtil().getUsernameAuthentication(),
76 ConnectionUtil.this.injectionModel.getMediatorUtils().getAuthenticationUtil().getPasswordAuthentication().toCharArray()
77 );
78 }
79 });
80 }
81 return httpClientBuilder;
82 }
83
84 public static <T> Map<String, String> getHeadersMap(HttpResponse<T> httpResponse) {
85 Map<String, String> sortedMap = ConnectionUtil.getHeadersMap(httpResponse.headers());
86 String responseCodeHttp = String.valueOf(httpResponse.statusCode());
87 sortedMap.put(":status", responseCodeHttp);
88 return sortedMap;
89 }
90
91 public static Map<String, String> getHeadersMap(HttpHeaders httpHeaders) {
92 Map<String, String> unsortedMap = httpHeaders.map()
93 .entrySet()
94 .stream()
95 .sorted(Entry.comparingByKey())
96 .map(entrySet -> new AbstractMap.SimpleEntry<>(
97 entrySet.getKey(),
98 String.join(", ", entrySet.getValue())
99 ))
100 .collect(Collectors.toMap(
101 AbstractMap.SimpleEntry::getKey,
102 AbstractMap.SimpleEntry::getValue
103 ));
104 return new TreeMap<>(unsortedMap);
105 }
106
107
108
109
110
111
112 public HttpResponse<String> checkConnectionResponse() throws IOException, InterruptedException, JSqlException {
113 var queryString = this.injectionModel.getMediatorUtils().getParameterUtil().getQueryStringFromEntries();
114 var testUrl = this.getUrlBase().replaceAll("\\?$", StringUtils.EMPTY);
115
116 if (StringUtils.isNotEmpty(queryString)) {
117 testUrl += "?"+ queryString;
118 }
119
120 String contentTypeRequest = "text/plain";
121
122 var body = this.injectionModel.getMediatorUtils().getParameterUtil().getRawRequest();
123
124 if (this.injectionModel.getMediatorUtils().getParameterUtil().isMultipartRequest()) {
125 body = body.replaceAll("(?s)\\\\n", "\r\n");
126 } else if (this.injectionModel.getMediatorUtils().getParameterUtil().isRequestSoap()) {
127 contentTypeRequest = "text/xml";
128 } else if (!this.injectionModel.getMediatorUtils().getParameterUtil().getListRequest().isEmpty()) {
129 contentTypeRequest = "application/x-www-form-urlencoded";
130 }
131
132
133 Builder httpRequest = HttpRequest.newBuilder();
134 try {
135 httpRequest.uri(
136 URI.create(
137 testUrl
138 .replace(InjectionModel.STAR, StringUtils.EMPTY)
139 )
140 );
141 } catch (IllegalArgumentException e) {
142 throw new JSqlException(e);
143 }
144 httpRequest.setHeader(HeaderUtil.CONTENT_TYPE_REQUEST, contentTypeRequest)
145 .timeout(Duration.ofSeconds(this.getTimeout()));
146
147 this.injectionModel.getMediatorUtils().getCsrfUtil().addHeaderToken(httpRequest);
148 this.injectionModel.getMediatorUtils().getDigestUtil().addHeaderToken(httpRequest);
149
150 httpRequest.method(this.typeRequest, BodyPublishers.ofString(body));
151
152
153 for (SimpleEntry<String, String> header: this.injectionModel.getMediatorUtils().getParameterUtil().getListHeader()) {
154 HeaderUtil.sanitizeHeaders(httpRequest, header);
155 }
156
157 return this.injectionModel.getMediatorUtils().getHeaderUtil().checkResponseHeader(httpRequest, body);
158 }
159
160 public void testConnection() throws IOException, InterruptedException, JSqlException {
161
162 LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, () -> I18nUtil.valueByKey("LOG_CONNECTION_TEST"));
163 this.getCookieManager().getCookieStore().removeAll();
164 HttpResponse<String> httpResponse = this.checkConnectionResponse();
165
166 if (
167 (httpResponse.statusCode() == 401 || httpResponse.statusCode() == 403)
168 && !this.injectionModel.getMediatorUtils().getPreferencesUtil().isNotProcessingCookies()
169 && (
170 this.injectionModel.getMediatorUtils().getCsrfUtil().isCsrf()
171 || this.injectionModel.getMediatorUtils().getDigestUtil().isDigest()
172 )
173 ) {
174 if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isProcessingCsrf()) {
175 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, () -> "Testing CSRF handshake from previous connection...");
176 } else if (StringUtils.isNotEmpty(this.injectionModel.getMediatorUtils().getDigestUtil().getTokenDigest())) {
177 LOGGER.log(LogLevelUtil.CONSOLE_INFORM, () -> "Testing Digest handshake from previous connection...");
178 }
179 httpResponse = this.checkConnectionResponse();
180 }
181
182 if (httpResponse.statusCode() >= 400 && !this.injectionModel.getMediatorUtils().getPreferencesUtil().isNotTestingConnection()) {
183 throw new InjectionFailureException(String.format("Connection failed: problem when calling %s", httpResponse.uri().toURL()));
184 }
185 }
186
187
188
189
190
191
192 public String getSourceLineFeed(String url) {
193 return this.getSource(url, true, false);
194 }
195
196 public String getSource(String url) {
197 return this.getSource(url, false, false);
198 }
199
200 public String getSource(String url, boolean isConnectIssueIgnored) {
201 return this.getSource(url, false, isConnectIssueIgnored);
202 }
203
204 public String getSource(String url, boolean lineFeed, boolean isConnectIssueIgnored) {
205 Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
206 msgHeader.put(Header.URL, url);
207
208 String pageSource = StringUtils.EMPTY;
209
210 try {
211 var httpRequest = HttpRequest.newBuilder()
212 .uri(URI.create(url))
213 .timeout(Duration.ofSeconds(this.getTimeout()))
214 .build();
215
216 HttpHeaders httpHeaders;
217 if (lineFeed) {
218 HttpResponse<Stream<String>> response = this.getHttpClient().build().send(httpRequest, BodyHandlers.ofLines());
219 pageSource = response.body().collect(Collectors.joining("\n"));
220 httpHeaders = response.headers();
221 } else {
222 HttpResponse<String> response = this.getHttpClient().build().send(httpRequest, BodyHandlers.ofString());
223 pageSource = response.body();
224 httpHeaders = response.headers();
225 }
226
227 msgHeader.put(Header.RESPONSE, ConnectionUtil.getHeadersMap(httpHeaders));
228 msgHeader.put(Header.HEADER, ConnectionUtil.getHeadersMap(httpRequest.headers()));
229
230 } catch (IOException e) {
231 if (!isConnectIssueIgnored) {
232 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
233 }
234 } catch (InterruptedException e) {
235 LOGGER.log(LogLevelUtil.IGNORE, e, e);
236 Thread.currentThread().interrupt();
237 } finally {
238 msgHeader.put(Header.SOURCE, pageSource);
239
240 var request = new Request();
241 request.setMessage(Interaction.MESSAGE_HEADER);
242 request.setParameters(msgHeader);
243 this.injectionModel.sendToViews(request);
244 }
245
246 return pageSource.trim();
247 }
248
249 public void setCustomUserAgent(Builder httpRequest) {
250 if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isUserAgentRandom()) {
251 String agents = this.injectionModel.getMediatorUtils().getUserAgentUtil().getCustomUserAgent();
252 List<String> listAgents = Stream.of(agents.split("[\\r\\n]+"))
253 .filter(q -> !q.matches("^#.*"))
254 .collect(Collectors.toList());
255 String randomElement = listAgents.get(this.randomForUserAgent.nextInt(listAgents.size()));
256 httpRequest.setHeader("User-Agent", randomElement);
257 }
258 }
259
260
261
262
263 public ConnectionUtil withMethodInjection(AbstractMethodInjection methodInjection) {
264 this.methodInjection = methodInjection;
265 return this;
266 }
267
268 public ConnectionUtil withTypeRequest(String typeRequest) {
269 this.typeRequest = typeRequest;
270 return this;
271 }
272
273
274
275
276 public String getUrlByUser() {
277 return this.urlByUser;
278 }
279
280 public void setUrlByUser(String urlByUser) {
281 this.urlByUser = urlByUser;
282 }
283
284 public String getUrlBase() {
285 return this.urlBase;
286 }
287
288 public void setUrlBase(String urlBase) {
289 this.urlBase = urlBase;
290 }
291
292 public AbstractMethodInjection getMethodInjection() {
293 return this.methodInjection;
294 }
295
296 public void setMethodInjection(AbstractMethodInjection methodInjection) {
297 this.methodInjection = methodInjection;
298 }
299
300 public String getTypeRequest() {
301 return this.typeRequest;
302 }
303
304 public void setTypeRequest(String typeRequest) {
305 this.typeRequest = typeRequest;
306 }
307
308
309
310
311 public Integer getTimeout() {
312 return this.injectionModel.getMediatorUtils().getPreferencesUtil().countConnectionTimeout();
313 }
314
315 public CookieManager getCookieManager() {
316 return this.cookieManager;
317 }
318 }