Skip to content

Commit 5b2b47a

Browse files
author
Mattia Bertorello
committed
Delete cached file if the signature verified fail
1 parent 1bfdf83 commit 5b2b47a

File tree

4 files changed

+67
-23
lines changed

4 files changed

+67
-23
lines changed

Diff for: arduino-core/src/cc/arduino/contributions/DownloadableContributionsDownloader.java

+19-10
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public void download(URL url, File tmpFile, Progress progress, String statusText
126126
}
127127

128128
public void download(URL url, File tmpFile, Progress progress, String statusText, ProgressListener progressListener, boolean noResume, boolean allowCache) throws Exception {
129-
FileDownloader downloader = new FileDownloader(url, tmpFile, allowCache);
129+
final FileDownloader downloader = new FileDownloader(url, tmpFile, allowCache);
130130
downloader.addObserver((o, arg) -> {
131131
FileDownloader me = (FileDownloader) o;
132132
String msg = "";
@@ -148,22 +148,24 @@ public void download(URL url, File tmpFile, Progress progress, String statusText
148148
public void downloadIndexAndSignature(MultiStepProgress progress, URL packageIndexUrl, ProgressListener progressListener, SignatureVerifier signatureVerifier) throws Exception {
149149

150150
// Extract the file name from the url
151-
String indexFileName = FilenameUtils.getName(packageIndexUrl.getPath());
152-
File packageIndex = BaseNoGui.indexer.getIndexFile(indexFileName);
151+
final String indexFileName = FilenameUtils.getName(packageIndexUrl.getPath());
152+
final File packageIndex = BaseNoGui.indexer.getIndexFile(indexFileName);
153153

154154
final String statusText = tr("Downloading platforms index...");
155155

156156
// Create temp files
157-
File packageIndexTemp = File.createTempFile(indexFileName, ".tmp");
157+
final File packageIndexTemp = File.createTempFile(indexFileName, ".tmp");
158158
try {
159159
// Download package index
160160
download(packageIndexUrl, packageIndexTemp, progress, statusText, progressListener, true, true);
161+
final URL signatureUrl = new URL(packageIndexUrl.toString() + ".sig");
161162

162163
if (verifyDomain(packageIndexUrl)) {
163-
URL signatureUrl = new URL(packageIndexUrl.toString() + ".sig");
164-
165164
if (checkSignature(progress, signatureUrl, progressListener, signatureVerifier, statusText, packageIndexTemp)) {
166165
Files.move(packageIndexTemp.toPath(), packageIndex.toPath(), StandardCopyOption.REPLACE_EXISTING);
166+
} else {
167+
log.info("The cached files have been removed. {} {}", packageIndexUrl, signatureUrl);
168+
FileDownloader.invalidateFiles(packageIndexUrl, signatureUrl);
167169
}
168170
} else {
169171
// Move the package index to the destination when the signature is not necessary
@@ -196,18 +198,25 @@ public boolean verifyDomain(URL url) {
196198

197199
public boolean checkSignature(MultiStepProgress progress, URL signatureUrl, ProgressListener progressListener, SignatureVerifier signatureVerifier, String statusText, File fileToVerify) throws Exception {
198200

201+
final boolean allowInsecurePackages =
202+
PreferencesData.getBoolean("allow_insecure_packages", false);
203+
if (allowInsecurePackages) {
204+
log.info("Allow insecure packages is true the signature will be skip and return always verified");
205+
return true;
206+
}
207+
199208
// Signature file name
200-
String signatureFileName = FilenameUtils.getName(signatureUrl.getPath());
201-
File packageIndexSignature = BaseNoGui.indexer.getIndexFile(signatureFileName);
202-
File packageIndexSignatureTemp = File.createTempFile(signatureFileName, ".tmp");
209+
final String signatureFileName = FilenameUtils.getName(signatureUrl.getPath());
210+
final File packageIndexSignature = BaseNoGui.indexer.getIndexFile(signatureFileName);
211+
final File packageIndexSignatureTemp = File.createTempFile(signatureFileName, ".tmp");
203212

204213

205214
try {
206215
// Download signature
207216
download(signatureUrl, packageIndexSignatureTemp, progress, statusText, progressListener, true);
208217

209218
// Verify the signature before move the files
210-
boolean signatureVerified = signatureVerifier.isSigned(fileToVerify, packageIndexSignatureTemp);
219+
final boolean signatureVerified = signatureVerifier.isSigned(fileToVerify, packageIndexSignatureTemp);
211220
if (signatureVerified) {
212221
log.info("Signature verified. url={}, signature url={}, file to verify={}, signature file={}", signatureUrl, signatureUrl, fileToVerify, packageIndexSignatureTemp);
213222
// Move if the signature is ok

Diff for: arduino-core/src/cc/arduino/contributions/libraries/LibraryInstaller.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import cc.arduino.contributions.ProgressListener;
3737
import cc.arduino.utils.ArchiveExtractor;
3838
import cc.arduino.utils.MultiStepProgress;
39+
import cc.arduino.utils.network.FileDownloader;
3940
import org.apache.commons.io.FilenameUtils;
4041
import org.apache.logging.log4j.LogManager;
4142
import org.apache.logging.log4j.Logger;
@@ -74,9 +75,10 @@ public synchronized void updateIndex(ProgressListener progressListener) throws E
7475
String signatureFileName = FilenameUtils.getName(new URL(Constants.LIBRARY_INDEX_URL).getPath());
7576
File libraryIndexTemp = File.createTempFile(signatureFileName, ".tmp");
7677
final URL libraryURL = new URL(Constants.LIBRARY_INDEX_URL);
78+
final URL libraryGzURL = new URL(Constants.LIBRARY_INDEX_URL_GZ);
7779
final String statusText = tr("Downloading libraries index...");
7880
try {
79-
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, libraryURL, new URL(Constants.LIBRARY_INDEX_URL_GZ));
81+
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, libraryURL, libraryGzURL);
8082
gZippedJsonDownloader.download(libraryIndexTemp, progress, statusText, progressListener, true);
8183
} catch (InterruptedException e) {
8284
// Download interrupted... just exit
@@ -98,7 +100,8 @@ public synchronized void updateIndex(ProgressListener progressListener) throws E
98100
// Step 3: Rescan index
99101
rescanLibraryIndex(progress, progressListener);
100102
} else {
101-
log.error("Fail to verify the signature of {}", libraryURL);
103+
FileDownloader.invalidateFiles(libraryGzURL, libraryURL, signatureUrl);
104+
log.error("Fail to verify the signature of {} the cached files have been removed", libraryURL);
102105
}
103106
} else {
104107
log.info("The domain is not selected to verify the signature. library index: {}", signatureUrl);

Diff for: arduino-core/src/cc/arduino/utils/network/FileDownloader.java

+31-5
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,18 @@
3434
import org.apache.logging.log4j.Logger;
3535
import processing.app.helpers.FileUtils;
3636

37+
import javax.script.ScriptException;
3738
import java.io.File;
3839
import java.io.IOException;
3940
import java.io.InputStream;
4041
import java.io.RandomAccessFile;
4142
import java.net.HttpURLConnection;
4243
import java.net.SocketTimeoutException;
44+
import java.net.URISyntaxException;
4345
import java.net.URL;
4446
import java.nio.file.Files;
4547
import java.nio.file.Paths;
48+
import java.util.Arrays;
4649
import java.util.Observable;
4750
import java.util.Optional;
4851

@@ -137,26 +140,49 @@ private void saveLocalFile() {
137140
}
138141
}
139142

143+
public static void invalidateFiles(URL... filesUrl) {
144+
// For each file delete the file cached if exist
145+
Arrays.stream(filesUrl).forEach(url -> {
146+
try {
147+
FileDownloaderCache.getFileCached(url).ifPresent(fileCached -> {
148+
try {
149+
log.info("Invalidate this file {} that comes from {}", fileCached.getLocalPath(), fileCached.getRemoteURL());
150+
fileCached.invalidateCache();
151+
} catch (Exception e) {
152+
log.warn("Fail to invalidate cache", e);
153+
}
154+
});
155+
} catch (URISyntaxException | NoSuchMethodException | ScriptException | IOException e) {
156+
log.warn("Fail to get the file cached during the file invalidation", e);
157+
}
158+
});
159+
160+
}
161+
140162
private void downloadFile(boolean noResume) throws InterruptedException {
141163

142164
try {
143165
setStatus(Status.CONNECTING);
144166

145-
final Optional<FileDownloaderCache.FileCached> fileCached = FileDownloaderCache.getFileCached(downloadUrl);
146-
if (fileCached.isPresent() && fileCached.get().isNotChange()) {
147-
final Optional<File> fileFromCache = getFileCached(fileCached.get());
148-
if (fileFromCache.isPresent()) {
167+
final Optional<FileDownloaderCache.FileCached> fileCachedOpt = FileDownloaderCache.getFileCached(downloadUrl);
168+
if (fileCachedOpt.isPresent()) {
169+
final FileDownloaderCache.FileCached fileCached = fileCachedOpt.get();
170+
171+
final Optional<File> fileFromCache = getFileCached(fileCached);
172+
if (fileCached.isNotChange() && fileFromCache.isPresent()) {
149173
// Copy the cached file in the destination file
150174
FileUtils.copyFile(fileFromCache.get(), outputFile);
151175
} else {
152176
openConnectionAndFillTheFile(noResume);
153177

154178
if (allowCache) {
155-
fileCached.get().updateCacheFile(outputFile);
179+
fileCached.updateCacheFile(outputFile);
156180
} else {
157181
log.info("The file {} was not cached because allow cache is false", downloadUrl);
158182
}
159183
}
184+
} else {
185+
openConnectionAndFillTheFile(noResume);
160186
}
161187
setStatus(Status.COMPLETE);
162188

Diff for: arduino-core/src/cc/arduino/utils/network/FileDownloaderCache.java

+12-6
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public class FileDownloaderCache {
117117
}
118118
}
119119

120-
public static Optional<FileCached> getFileCached(final URL remoteURL)
120+
static Optional<FileCached> getFileCached(final URL remoteURL)
121121
throws URISyntaxException, NoSuchMethodException, ScriptException,
122122
IOException {
123123
// Return always and empty file if the cache is not enable
@@ -268,7 +268,8 @@ public FileCached(String remoteURL, String localPath, String eTag, String lastET
268268
@JsonIgnore
269269
public boolean isExpire() {
270270
// Check if the file is expire
271-
return this.getExpiresTime().isBefore(LocalDateTime.now());
271+
final LocalDateTime now = LocalDateTime.now();
272+
return this.getExpiresTime().isBefore(now) || this.getExpiresTime().isEqual(now);
272273
}
273274

274275
@JsonIgnore
@@ -298,15 +299,15 @@ public boolean exists() {
298299
}
299300

300301
@JsonIgnore
301-
public Optional<File> getFileFromCache() {
302+
Optional<File> getFileFromCache() {
302303
if (md5Check()) {
303304
return Optional.of(Paths.get(localPath).toFile());
304305
}
305306
return Optional.empty();
306307

307308
}
308309

309-
public synchronized void updateCacheFile(File fileToCache) throws Exception {
310+
synchronized void updateCacheFile(File fileToCache) throws Exception {
310311
Path cacheFilePath = Paths.get(localPath);
311312

312313
// If the cache directory does not exist create it
@@ -336,6 +337,11 @@ public synchronized void updateCacheFile(File fileToCache) throws Exception {
336337

337338
}
338339

340+
synchronized void invalidateCache() throws IOException {
341+
cachedFiles.remove(remoteURL);
342+
Files.deleteIfExists(Paths.get(localPath));
343+
}
344+
339345
private String calculateMD5() throws IOException, NoSuchAlgorithmException {
340346
if (exists()) {
341347
return FileHash.hash(Paths.get(localPath).toFile(), "MD5");
@@ -344,7 +350,7 @@ private String calculateMD5() throws IOException, NoSuchAlgorithmException {
344350
}
345351

346352
@JsonIgnore
347-
public boolean md5Check() {
353+
boolean md5Check() {
348354
try {
349355
return !Objects.isNull(getMD5()) && Objects.equals(calculateMD5(), getMD5());
350356
} catch (Exception e) {
@@ -354,7 +360,7 @@ public boolean md5Check() {
354360
}
355361

356362
@JsonIgnore
357-
public LocalDateTime getExpiresTime() {
363+
LocalDateTime getExpiresTime() {
358364
final int maxAge;
359365
if (cacheControl != null) {
360366
maxAge = cacheControl.getMaxAge();

0 commit comments

Comments
 (0)