Skip to content

Commit 5157688

Browse files
author
Mattia Bertorello
committed
Split download and check signature, add check signature to library index
1 parent 2596ece commit 5157688

File tree

3 files changed

+81
-47
lines changed

3 files changed

+81
-47
lines changed

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

+47-29
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,22 @@
3333
import cc.arduino.utils.MultiStepProgress;
3434
import cc.arduino.utils.Progress;
3535
import cc.arduino.utils.network.FileDownloader;
36-
import org.slf4j.Logger;
37-
import org.slf4j.LoggerFactory;
36+
import org.apache.logging.log4j.LogManager;
37+
import org.apache.logging.log4j.Logger;
3838
import processing.app.BaseNoGui;
39+
import processing.app.PreferencesData;
3940

4041
import java.io.File;
4142
import java.net.URL;
4243
import java.nio.file.*;
44+
import java.util.LinkedList;
4345
import java.util.List;
4446

4547
import static processing.app.I18n.format;
4648
import static processing.app.I18n.tr;
4749

4850
public class DownloadableContributionsDownloader {
49-
private static Logger log = LoggerFactory.getLogger(DownloadableContributionsDownloader.class);
51+
private static Logger log = LogManager.getLogger(DownloadableContributionsDownloader.class);
5052

5153
private final File stagingFolder;
5254

@@ -147,55 +149,71 @@ public void downloadIndexAndSignature(MultiStepProgress progress, List<String> d
147149

148150
// Extract the file name from the url
149151
URL packageIndexUrl = new URL(packageIndexUrlString);
150-
URL packageIndexSignatureUrl = new URL(packageIndexUrlString + ".sig");
151152
String[] urlPathParts = packageIndexUrl.getFile().split("/");
152153
File packageIndex = BaseNoGui.indexer.getIndexFile(urlPathParts[urlPathParts.length - 1]);
153-
// Signature file name
154-
File packageIndexSignature = BaseNoGui.indexer.getIndexFile(urlPathParts[urlPathParts.length - 1] + ".sig");
155154

156155
final String statusText = tr("Downloading platforms index...");
157156
downloadedFilesAccumulator.add(packageIndex.getName());
158157

159158
// Create temp files
160159
File packageIndexTemp = File.createTempFile(packageIndexUrl.getPath(), ".tmp");
161-
File packageIndexSignatureTemp = File.createTempFile(packageIndexSignatureUrl.getPath(), ".tmp");
162160
try {
163161
// Download package index
164162
download(packageIndexUrl, packageIndexTemp, progress, statusText, progressListener, true);
165-
try {
166-
// Download signature
167-
download(packageIndexSignatureUrl, packageIndexSignatureTemp, progress, statusText, progressListener, true);
168-
169-
// Verify the signature before move the files
170-
boolean signatureVerified = signatureVerifier.isSigned(packageIndexTemp, packageIndexSignatureTemp);
171-
if (signatureVerified) {
172-
// Move if the signature is ok
173-
Files.move(packageIndexTemp.toPath(), packageIndex.toPath(), StandardCopyOption.REPLACE_EXISTING);
174-
Files.move(packageIndexSignatureTemp.toPath(), packageIndexSignature.toPath(), StandardCopyOption.REPLACE_EXISTING);
175-
downloadedFilesAccumulator.add(packageIndexSignature.getName());
176-
} else {
177-
downloadedFilesAccumulator.remove(packageIndex.getName());
178-
log.error("{} file signature verification failed. File ignored.", packageIndexSignatureUrl);
179-
System.err.println(format(tr("{0} file signature verification failed. File ignored."), packageIndexUrlString));
163+
final List<String> domain = new LinkedList<>(PreferencesData.getCollection("http.signature_verify_domains"));
164+
// Default domain
165+
domain.add("downloads.arduino.cc");
180166

181-
}
182-
} catch (Exception e) {
183-
log.error("Cannot download the signature from {} the package will be install in any case", packageIndexSignatureUrl, e);
184-
if (packageIndexTemp.length() > 0) {
167+
if (domain.contains(packageIndexUrl.getHost())) {
168+
URL signatureUrl = new URL(packageIndexUrl.toString() + ".sig");
169+
170+
if (checkSignature(progress, downloadedFilesAccumulator, signatureUrl, progressListener, signatureVerifier, statusText, packageIndexTemp)) {
185171
Files.move(packageIndexTemp.toPath(), packageIndex.toPath(), StandardCopyOption.REPLACE_EXISTING);
186172
} else {
187-
log.error("The temporarily package index file is empty (path:{},url:{}), It cannot be move there {} ",
188-
packageIndexTemp.toPath(), packageIndexUrlString, packageIndex.toPath());
173+
downloadedFilesAccumulator.remove(packageIndex.getName());
189174
}
175+
} else {
176+
log.info("The domain is not selected to verify the signature. domain list: {}, packageIndex: {}", domain, packageIndexUrl);
190177
}
191-
192178
} catch (Exception e) {
193179
downloadedFilesAccumulator.remove(packageIndex.getName());
194180
throw e;
195181
} finally {
196182
// Delete useless temp file
197183
Files.deleteIfExists(packageIndexTemp.toPath());
184+
}
185+
}
186+
187+
public boolean checkSignature(MultiStepProgress progress, List<String> downloadedFilesAccumulator, URL signatureUrl, ProgressListener progressListener, SignatureVerifier signatureVerifier, String statusText, File fileToVerify) throws Exception {
188+
189+
File packageIndexSignatureTemp = File.createTempFile(signatureUrl.getPath(), ".tmp");
190+
// Signature file name
191+
String[] urlPathParts = signatureUrl.getFile().split("/");
192+
File packageIndexSignature = BaseNoGui.indexer.getIndexFile(urlPathParts[urlPathParts.length - 1]);
193+
194+
try {
195+
// Download signature
196+
download(signatureUrl, packageIndexSignatureTemp, progress, statusText, progressListener, true);
197+
198+
// Verify the signature before move the files
199+
boolean signatureVerified = signatureVerifier.isSigned(fileToVerify, packageIndexSignatureTemp);
200+
if (signatureVerified) {
201+
log.info("Signature verified. url={}, signature url={}, file to verify={}, signature file={}", signatureUrl, signatureUrl, fileToVerify, packageIndexSignatureTemp);
202+
// Move if the signature is ok
203+
Files.move(packageIndexSignatureTemp.toPath(), packageIndexSignature.toPath(), StandardCopyOption.REPLACE_EXISTING);
204+
downloadedFilesAccumulator.add(packageIndexSignature.getName());
205+
} else {
206+
log.error("{} file signature verification failed. File ignored.", signatureUrl);
207+
System.err.println(format(tr("{0} file signature verification failed. File ignored."), signatureUrl.toString()));
208+
}
209+
return signatureVerified;
210+
} catch (Exception e) {
211+
log.error("Cannot download the signature from {} the package will be discard", signatureUrl, e);
212+
throw e;
213+
} finally {
198214
Files.deleteIfExists(packageIndexSignatureTemp.toPath());
199215
}
216+
200217
}
218+
201219
}

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

+28-13
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@
3131

3232
import cc.arduino.Constants;
3333
import cc.arduino.contributions.DownloadableContributionsDownloader;
34+
import cc.arduino.contributions.GPGDetachedSignatureVerifier;
3435
import cc.arduino.contributions.GZippedJsonDownloader;
3536
import cc.arduino.contributions.ProgressListener;
3637
import cc.arduino.utils.ArchiveExtractor;
3738
import cc.arduino.utils.MultiStepProgress;
39+
import org.apache.logging.log4j.LogManager;
40+
import org.apache.logging.log4j.Logger;
3841
import processing.app.BaseNoGui;
3942
import processing.app.I18n;
4043
import processing.app.Platform;
@@ -45,47 +48,59 @@
4548
import java.net.URL;
4649
import java.nio.file.Files;
4750
import java.nio.file.StandardCopyOption;
51+
import java.util.LinkedList;
52+
import java.util.List;
4853
import java.util.Optional;
4954

5055
import static processing.app.I18n.tr;
5156

5257
public class LibraryInstaller {
58+
private static Logger log = LogManager.getLogger(LibraryInstaller.class);
5359

5460
private final Platform platform;
61+
private final GPGDetachedSignatureVerifier signatureVerifier;
5562

56-
public LibraryInstaller(Platform platform) {
63+
public LibraryInstaller(Platform platform, GPGDetachedSignatureVerifier signatureVerifier) {
5764
this.platform = platform;
65+
this.signatureVerifier = signatureVerifier;
5866
}
5967

6068
public synchronized void updateIndex(ProgressListener progressListener) throws Exception {
6169
final MultiStepProgress progress = new MultiStepProgress(3);
6270

71+
List<String> downloadedFilesAccumulator = new LinkedList<>();
72+
6373
DownloadableContributionsDownloader downloader = new DownloadableContributionsDownloader(BaseNoGui.librariesIndexer.getStagingFolder());
6474
// Step 1: Download index
6575
File outputFile = BaseNoGui.librariesIndexer.getIndexFile();
6676
// Create temp files
6777
File libraryIndexTemp = File.createTempFile(new URL(Constants.LIBRARY_INDEX_URL).getPath(), ".tmp");
78+
final URL libraryURL = new URL(Constants.LIBRARY_INDEX_URL);
79+
final String statusText = tr("Downloading libraries index...");
6880
try {
69-
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, new URL(Constants.LIBRARY_INDEX_URL), new URL(Constants.LIBRARY_INDEX_URL_GZ));
70-
gZippedJsonDownloader.download(libraryIndexTemp, progress, tr("Downloading libraries index..."), progressListener);
81+
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, libraryURL, new URL(Constants.LIBRARY_INDEX_URL_GZ));
82+
gZippedJsonDownloader.download(libraryIndexTemp, progress, statusText, progressListener);
7183
} catch (InterruptedException e) {
7284
// Download interrupted... just exit
7385
return;
7486
}
7587
progress.stepDone();
7688

77-
// TODO: Check downloaded index
78-
79-
// Replace old index with the updated one
80-
if (libraryIndexTemp.length() > 0) {
81-
Files.move(libraryIndexTemp.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
82-
}
89+
URL signatureUrl = new URL(libraryURL.toString() + ".sig");
90+
if (downloader.checkSignature(progress, downloadedFilesAccumulator, signatureUrl, progressListener, signatureVerifier, statusText, libraryIndexTemp)) {
91+
// Replace old index with the updated one
92+
if (libraryIndexTemp.length() > 0) {
93+
Files.move(libraryIndexTemp.toPath(), outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
94+
}
8395

84-
// Step 2: Parse index
85-
BaseNoGui.librariesIndexer.parseIndex();
96+
// Step 2: Parse index
97+
BaseNoGui.librariesIndexer.parseIndex();
8698

87-
// Step 3: Rescan index
88-
rescanLibraryIndex(progress, progressListener);
99+
// Step 3: Rescan index
100+
rescanLibraryIndex(progress, progressListener);
101+
} else {
102+
log.error("Fail to verify the signature of {}", libraryURL);
103+
}
89104
}
90105

91106
public synchronized void install(ContributedLibrary lib, Optional<ContributedLibrary> mayReplacedLib, ProgressListener progressListener) throws Exception {

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

+6-5
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
import org.apache.commons.exec.DefaultExecutor;
4242
import org.apache.commons.exec.Executor;
4343
import org.apache.commons.exec.PumpStreamHandler;
44-
import org.slf4j.Logger;
45-
import org.slf4j.LoggerFactory;
44+
import org.apache.logging.log4j.LogManager;
45+
import org.apache.logging.log4j.Logger;
4646
import processing.app.BaseNoGui;
4747
import processing.app.I18n;
4848
import processing.app.Platform;
@@ -63,7 +63,7 @@
6363
import static processing.app.I18n.tr;
6464

6565
public class ContributionInstaller {
66-
private static Logger log = LoggerFactory.getLogger(ContributionInstaller.class);
66+
private static Logger log = LogManager.getLogger(ContributionInstaller.class);
6767

6868
private final Platform platform;
6969
private final SignatureVerifier signatureVerifier;
@@ -267,10 +267,11 @@ public synchronized List<String> remove(ContributedPlatform contributedPlatform)
267267
// now try to remove the containing TOOL_NAME folder
268268
// (and silently fail if another version of the tool is installed)
269269
try {
270-
Files.deleteIfExists(destFolder.getParentFile().toPath());
270+
Files.delete(destFolder.getParentFile().toPath());
271271
} catch (Exception e) {
272272
// ignore
273-
log.error(e.getMessage(), e);
273+
log.info("The directory is not empty there is another version installed. directory {}",
274+
destFolder.getParentFile().toPath(), e);
274275
}
275276
}
276277

0 commit comments

Comments
 (0)