mirror of
https://github.com/arduino/Arduino.git
synced 2024-11-29 10:24:12 +01:00
Use verifyDomain also for the library index
This commit is contained in:
parent
e1e4fb30b8
commit
1bc994ec86
@ -160,11 +160,8 @@ public class DownloadableContributionsDownloader {
|
||||
try {
|
||||
// Download package index
|
||||
download(packageIndexUrl, packageIndexTemp, progress, statusText, progressListener, true);
|
||||
final List<String> domain = new LinkedList<>(PreferencesData.getCollection("http.signature_verify_domains"));
|
||||
// Default domain
|
||||
domain.add("downloads.arduino.cc");
|
||||
|
||||
if (domain.contains(packageIndexUrl.getHost())) {
|
||||
if (verifyDomain(packageIndexUrl)) {
|
||||
URL signatureUrl = new URL(packageIndexUrl.toString() + ".sig");
|
||||
|
||||
if (checkSignature(progress, downloadedFilesAccumulator, signatureUrl, progressListener, signatureVerifier, statusText, packageIndexTemp)) {
|
||||
@ -173,7 +170,7 @@ public class DownloadableContributionsDownloader {
|
||||
downloadedFilesAccumulator.remove(packageIndex.getName());
|
||||
}
|
||||
} else {
|
||||
log.info("The domain is not selected to verify the signature. domain list: {}, packageIndex: {}", domain, packageIndexUrl);
|
||||
log.info("The domain is not selected to verify the signature. packageIndex: {}", packageIndexUrl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
downloadedFilesAccumulator.remove(packageIndex.getName());
|
||||
@ -184,6 +181,20 @@ public class DownloadableContributionsDownloader {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean verifyDomain(URL url) {
|
||||
final List<String> domain = new LinkedList<>(PreferencesData.getCollection("http.signature_verify_domains"));
|
||||
if (domain.size() == 0) {
|
||||
// Default domain
|
||||
domain.add("downloads.arduino.cc");
|
||||
}
|
||||
if (domain.contains(url.getHost())) {
|
||||
return true;
|
||||
} else {
|
||||
log.info("The domain is not selected to verify the signature. domain list: {}, url: {}", domain, url);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkSignature(MultiStepProgress progress, List<String> downloadedFilesAccumulator, URL signatureUrl, ProgressListener progressListener, SignatureVerifier signatureVerifier, String statusText, File fileToVerify) throws Exception {
|
||||
|
||||
File packageIndexSignatureTemp = File.createTempFile(signatureUrl.getPath(), ".tmp");
|
||||
|
@ -87,20 +87,25 @@ public class LibraryInstaller {
|
||||
progress.stepDone();
|
||||
|
||||
URL signatureUrl = new URL(libraryURL.toString() + ".sig");
|
||||
if (downloader.checkSignature(progress, downloadedFilesAccumulator, signatureUrl, progressListener, signatureVerifier, statusText, libraryIndexTemp)) {
|
||||
// Replace old index with the updated one
|
||||
if (libraryIndexTemp.length() > 0) {
|
||||
Files.move(libraryIndexTemp.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
if (downloader.verifyDomain(signatureUrl)) {
|
||||
if (downloader.checkSignature(progress, downloadedFilesAccumulator, signatureUrl, progressListener, signatureVerifier, statusText, libraryIndexTemp)) {
|
||||
// Replace old index with the updated one
|
||||
if (libraryIndexTemp.length() > 0) {
|
||||
Files.move(libraryIndexTemp.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
// Step 2: Parse index
|
||||
BaseNoGui.librariesIndexer.parseIndex();
|
||||
|
||||
// Step 3: Rescan index
|
||||
rescanLibraryIndex(progress, progressListener);
|
||||
} else {
|
||||
log.error("Fail to verify the signature of {}", libraryURL);
|
||||
}
|
||||
|
||||
// Step 2: Parse index
|
||||
BaseNoGui.librariesIndexer.parseIndex();
|
||||
|
||||
// Step 3: Rescan index
|
||||
rescanLibraryIndex(progress, progressListener);
|
||||
} else {
|
||||
log.error("Fail to verify the signature of {}", libraryURL);
|
||||
log.info("The domain is not selected to verify the signature. library index: {}", signatureUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public synchronized void install(ContributedLibrary lib, Optional<ContributedLibrary> mayReplacedLib, ProgressListener progressListener) throws Exception {
|
||||
|
@ -3,99 +3,22 @@ package cc.arduino.utils.network;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Represents a HTTP Cache-Control response header and parses it from string.
|
||||
*
|
||||
* <p>Note: This class ignores <tt>1#field-name</tt> parameter for
|
||||
* <tt>private</tt> and <tt>no-cache</tt> directive and cache extensions.</p>
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">HTTP/1.1 section 14.9</a>
|
||||
*/
|
||||
public class CacheControl {
|
||||
|
||||
|
||||
// copied from org.apache.abdera.protocol.util.CacheControlUtil
|
||||
// see org.apache.abdera.protocol.util.CacheControlUtil
|
||||
private static final Pattern PATTERN
|
||||
= Pattern.compile("\\s*([\\w\\-]+)\\s*(=)?\\s*(\\-?\\d+|\\\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)+\\\")?\\s*");
|
||||
|
||||
/**
|
||||
* Corresponds to the <tt>max-age</tt> cache control directive.
|
||||
* The default value is <tt>-1</tt>, i.e. not specified.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
|
||||
*/
|
||||
private int maxAge = -1;
|
||||
|
||||
/**
|
||||
* Corresponds to the <tt>s-maxage</tt> cache control directive.
|
||||
* The default value is <tt>-1</tt>, i.e. not specified.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">HTTP/1.1 section 14.9.3</a>
|
||||
*/
|
||||
private int sMaxAge = -1;
|
||||
|
||||
/**
|
||||
* Whether the <tt>must-revalidate</tt> directive is specified.
|
||||
* The default value is <tt>false</tt>.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
|
||||
*/
|
||||
private boolean isMustRevalidate = false;
|
||||
|
||||
/**
|
||||
* Whether the <tt>no-cache</tt> directive is specified.
|
||||
* The default value is <tt>false</tt>.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
|
||||
*/
|
||||
private boolean isNoCache = false;
|
||||
|
||||
/**
|
||||
* Whether the <tt>no-store</tt> directive is specified.
|
||||
* The default value is <tt>false</tt>.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2">HTTP/1.1 section 14.9.2</a>
|
||||
*/
|
||||
private boolean isNoStore = false;
|
||||
|
||||
/**
|
||||
* Whether the <tt>no-transform</tt> directive is specified.
|
||||
* The default value is <tt>false</tt>.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5">HTTP/1.1 section 14.9.5</a>
|
||||
*/
|
||||
private boolean isNoTransform = false;
|
||||
|
||||
/**
|
||||
* Whether the <tt>private</tt> directive is specified.
|
||||
* The default value is <tt>false</tt>.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
|
||||
*/
|
||||
private boolean isPrivate = false;
|
||||
|
||||
/**
|
||||
* Whether the <tt>public</tt> directive is specified.
|
||||
* The default value is <tt>false</tt>.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1">HTTP/1.1 section 14.9.1</a>
|
||||
*/
|
||||
private boolean isPublic = false;
|
||||
|
||||
/**
|
||||
* Whether the <tt>proxy-revalidate</tt> directive is specified.
|
||||
* The default value is <tt>false</tt>.
|
||||
*
|
||||
* @see <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4">HTTP/1.1 section 14.9.4</a>
|
||||
*/
|
||||
private boolean isProxyRevalidate = false;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of CacheControl by parsing the supplied string.
|
||||
*
|
||||
* @param value A value the Cache-Control header.
|
||||
*/
|
||||
public static CacheControl valueOf(String value) {
|
||||
CacheControl cc = new CacheControl();
|
||||
|
||||
@ -105,22 +28,12 @@ public class CacheControl {
|
||||
switch (matcher.group(1).toLowerCase()) {
|
||||
case "max-age":
|
||||
cc.setMaxAge(Integer.parseInt(matcher.group(3))); break;
|
||||
case "s-maxage":
|
||||
cc.setSMaxAge(Integer.parseInt(matcher.group(3))); break;
|
||||
case "must-revalidate":
|
||||
cc.setMustRevalidate(true); break;
|
||||
case "no-cache":
|
||||
cc.setNoCache(true); break;
|
||||
case "no-store":
|
||||
cc.setNoStore(true); break;
|
||||
case "no-transform":
|
||||
cc.setNoTransform(true); break;
|
||||
case "private":
|
||||
cc.setPrivate(true); break;
|
||||
case "public":
|
||||
cc.setPublic(true); break;
|
||||
case "proxy-revalidate":
|
||||
cc.setProxyRevalidate(true); break;
|
||||
default: //ignore
|
||||
}
|
||||
}
|
||||
@ -128,25 +41,6 @@ public class CacheControl {
|
||||
return cc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <tt>max-age</tt>, or <tt>s-maxage</tt> according to whether
|
||||
* considering a shared cache, or a private cache. If shared cache and the
|
||||
* <tt>s-maxage</tt> is negative (i.e. not set), then returns
|
||||
* <tt>max-age</tt> instead.
|
||||
*
|
||||
* @param sharedCache <tt>true</tt> for a shared cache,
|
||||
* or <tt>false</tt> for a private cache
|
||||
* @return A {@link #maxAge}, or {@link #sMaxAge} according to the given
|
||||
* sharedCache argument.
|
||||
*/
|
||||
public int getMaxAge(boolean sharedCache) {
|
||||
if (sharedCache) {
|
||||
return sMaxAge >= 0 ? sMaxAge : maxAge;
|
||||
} else {
|
||||
return maxAge;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMaxAge(int maxAge) {
|
||||
this.maxAge = maxAge;
|
||||
}
|
||||
@ -155,14 +49,6 @@ public class CacheControl {
|
||||
return maxAge;
|
||||
}
|
||||
|
||||
public int getSMaxAge() {
|
||||
return sMaxAge;
|
||||
}
|
||||
|
||||
public void setSMaxAge(int sMaxAge) {
|
||||
this.sMaxAge = sMaxAge;
|
||||
}
|
||||
|
||||
public boolean isMustRevalidate() {
|
||||
return isMustRevalidate;
|
||||
}
|
||||
@ -187,50 +73,13 @@ public class CacheControl {
|
||||
isNoStore = noStore;
|
||||
}
|
||||
|
||||
public boolean isNoTransform() {
|
||||
return isNoTransform;
|
||||
}
|
||||
|
||||
public void setNoTransform(boolean noTransform) {
|
||||
isNoTransform = noTransform;
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return isPrivate;
|
||||
}
|
||||
|
||||
public void setPrivate(boolean aPrivate) {
|
||||
isPrivate = aPrivate;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
public void setPublic(boolean aPublic) {
|
||||
isPublic = aPublic;
|
||||
}
|
||||
|
||||
public boolean isProxyRevalidate() {
|
||||
return isProxyRevalidate;
|
||||
}
|
||||
|
||||
public void setProxyRevalidate(boolean proxyRevalidate) {
|
||||
isProxyRevalidate = proxyRevalidate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CacheControl{" +
|
||||
"maxAge=" + maxAge +
|
||||
", sMaxAge=" + sMaxAge +
|
||||
", isMustRevalidate=" + isMustRevalidate +
|
||||
", isNoCache=" + isNoCache +
|
||||
", isNoStore=" + isNoStore +
|
||||
", isNoTransform=" + isNoTransform +
|
||||
", isPrivate=" + isPrivate +
|
||||
", isPublic=" + isPublic +
|
||||
", isProxyRevalidate=" + isProxyRevalidate +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user