Skip to content

Commit

Permalink
validate bundle and extension download
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeloffner committed Dec 20, 2024
1 parent d089db1 commit 5c2149f
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 16 deletions.
80 changes: 75 additions & 5 deletions core/src/main/java/lucee/commons/net/HTTPUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -38,6 +41,7 @@

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.message.BasicHeader;

import lucee.commons.digest.Hash;
import lucee.commons.io.IOUtil;
Expand Down Expand Up @@ -694,10 +698,77 @@ public static boolean isSecure(URL url) {
return StringUtil.indexOfIgnoreCase(url.getProtocol(), "https") != -1;
}

public static void validateDownload(URL url, HttpResponse response, Resource res, boolean deleteFileWhenInvalid, Exception cause) throws IOException {
public static interface HeadersCollection {
public Header[] getHeaders(String name);
}

public static class HeadersHttpURLConnection implements HeadersCollection {

private HttpURLConnection conn;

public HeadersHttpURLConnection(HttpURLConnection conn) {
this.conn = conn;
}

@Override
public Header[] getHeaders(String name) {
String val = conn.getHeaderField(name);
if (!StringUtil.isEmpty(val, true)) {
return new Header[] { new BasicHeader(name, val) };
}
return null;
}
}

public static class HeadersHTTPResponse implements HeadersCollection {

private HTTPResponse response;

public HeadersHTTPResponse(HTTPResponse response) {
this.response = response;
}

@Override
public Header[] getHeaders(String name) {
List<Header> list = new ArrayList<>();
for (lucee.commons.net.http.Header header: response.getAllHeaders()) {
if (name.equals(header.getName())) {
list.add(new BasicHeader(header.getName(), header.getValue()));
}
}
return list.toArray(new Header[list.size()]);
}
}

public static class HeadersHttpResponse implements HeadersCollection {

private HttpResponse response;

public HeadersHttpResponse(HttpResponse response) {
this.response = response;
}

@Override
public Header[] getHeaders(String name) {
return response.getHeaders(name);
}
}

public static void validateDownload(URL url, HttpURLConnection conn, Resource res, boolean deleteFileWhenInvalid, Exception cause) throws IOException {
_validateDownload(url, new HeadersHttpURLConnection(conn), res, deleteFileWhenInvalid, cause);
}

public static void validateDownload(URL url, HTTPResponse rsp, Resource res, boolean deleteFileWhenInvalid, Exception cause) throws IOException {
_validateDownload(url, new HeadersHTTPResponse(rsp), res, deleteFileWhenInvalid, cause);
}

public static void validateDownload(URL url, HttpResponse rsp, Resource res, boolean deleteFileWhenInvalid, Exception cause) throws IOException {
_validateDownload(url, new HeadersHttpResponse(rsp), res, deleteFileWhenInvalid, cause);
}

private static void _validateDownload(URL url, HeadersCollection headersCollection, Resource res, boolean deleteFileWhenInvalid, Exception cause) throws IOException {
// in case of an exception, the file may was not created
if (cause != null && !res.exists()) return;

Header[] headers;
Header h;
String label, name;
Expand All @@ -706,7 +777,7 @@ public static void validateDownload(URL url, HttpResponse response, Resource res
name = e.getKey();
label = name.toUpperCase();
for (String hn: e.getValue()) {
headers = response.getHeaders(hn);
headers = headersCollection.getHeaders(hn);
if (headers != null && headers.length > 0) {
h = headers[0];
if (!StringUtil.isEmpty(h.getValue(), true)) {
Expand All @@ -717,7 +788,6 @@ public static void validateDownload(URL url, HttpResponse response, Resource res
else if ("sha256".equalsIgnoreCase(name)) fileHash = Hash.sha256(res);
else if ("sha512".equalsIgnoreCase(name)) fileHash = Hash.sha512(res);
else continue;

if (!fileHash.equalsIgnoreCase(h.getValue())) {
if (deleteFileWhenInvalid) {
res.remove(true);
Expand All @@ -739,7 +809,7 @@ public static void validateDownload(URL url, HttpResponse response, Resource res

// Digest validation
for (String hn: VALIDATION_HEADERS) {
headers = response.getHeaders(hn);
headers = headersCollection.getHeaders(hn);
if (headers != null && headers.length > 0) {
h = headers[0];
String raw = h.getValue();
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/lucee/runtime/config/DeployHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import lucee.commons.lang.StringUtil;
import lucee.commons.lang.types.RefBoolean;
import lucee.commons.lang.types.RefBooleanImpl;
import lucee.commons.net.HTTPUtil;
import lucee.commons.net.http.HTTPEngine;
import lucee.commons.net.http.HTTPResponse;
import lucee.commons.net.http.Header;
Expand Down Expand Up @@ -428,6 +429,9 @@ public static Resource downloadExtension(Config config, ExtensionDefintion ed, L
Resource res = SystemUtil.getTempDirectory().getRealResource(ed.getId() + "-" + ed.getVersion() + ".lex");
ResourceUtil.touch(res);
IOUtil.copy(rsp.getContentAsStream(), res, true);

HTTPUtil.validateDownload(url, rsp, res, true, null);

if (log != null) log.info("main", "Downloaded extension [" + ed + "] to [" + res + "]");
return res;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@
import lucee.commons.io.SystemUtil;
import lucee.commons.io.log.Log;
import lucee.commons.io.log.LogUtil;
import lucee.commons.io.res.Resource;
import lucee.commons.io.res.util.ResourceUtil;
import lucee.commons.lang.ExceptionUtil;
import lucee.commons.lang.Pair;
import lucee.commons.lang.StringUtil;
import lucee.commons.net.HTTPUtil;
import lucee.commons.net.http.HTTPResponse;
import lucee.commons.net.http.httpclient.HTTPEngine4Impl;
import lucee.loader.engine.CFMLEngine;
Expand Down Expand Up @@ -358,8 +361,10 @@ public File downloadBundle(BundleDefinition bd) throws IOException {
}

}

IOUtil.copy((InputStream) conn.getContent(), new FileOutputStream(jar), true, true);
Resource tmp = SystemUtil.getTempFile("jar", false);
IOUtil.copy((InputStream) conn.getContent(), tmp.getOutputStream(), true, true);
HTTPUtil.validateDownload(updateUrl, conn, tmp, true, null);
ResourceUtil.toFile(tmp).renameTo(jar);
conn.disconnect();
return jar;
/*
Expand Down
7 changes: 0 additions & 7 deletions core/src/main/java/lucee/runtime/thread/ThreadUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import javax.servlet.http.HttpSession;

import lucee.aprint;
import lucee.print;
import lucee.commons.io.DevNullOutputStream;
import lucee.commons.io.SystemUtil;
import lucee.commons.io.log.LogUtil;
Expand Down Expand Up @@ -256,11 +255,6 @@ public static ExecutorService createExecutorService(int maxThreads, boolean allo
return Executors.newFixedThreadPool(maxThreads);
}

public static void main(String[] args) {
ExecutorService t = createExecutorService();
print.e(t);
}

public static ExecutorService createExecutorService() {
if (SystemUtil.JAVA_VERSION >= SystemUtil.JAVA_VERSION_19) {
// FUTURE use newVirtualThreadPerTaskExecutor natively
Expand All @@ -271,7 +265,6 @@ public static ExecutorService createExecutorService() {
return (ExecutorService) methodHandle.invoke();
}
catch (Throwable e) {
print.e(e);
ExceptionUtil.rethrowIfNecessary(e);
LogUtil.log("threading", e);
}
Expand Down
2 changes: 1 addition & 1 deletion loader/build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<project default="core" basedir="." name="Lucee"
xmlns:resolver="antlib:org.apache.maven.resolver.ant">

<property name="version" value="6.2.0.240-SNAPSHOT"/>
<property name="version" value="6.2.0.241-SNAPSHOT"/>

<taskdef uri="antlib:org.apache.maven.resolver.ant" resource="org/apache/maven/resolver/ant/antlib.xml">
<classpath>
Expand Down
2 changes: 1 addition & 1 deletion loader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>org.lucee</groupId>
<artifactId>lucee</artifactId>
<version>6.2.0.240-SNAPSHOT</version>
<version>6.2.0.241-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Lucee Loader Build</name>
Expand Down

0 comments on commit 5c2149f

Please sign in to comment.