@@ -17,7 +17,6 @@ package commands
17
17
18
18
import (
19
19
"context"
20
- "errors"
21
20
"fmt"
22
21
"io/ioutil"
23
22
"net/url"
@@ -37,6 +36,7 @@ import (
37
36
"github.com/arduino/arduino-cli/configuration"
38
37
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
39
38
paths "github.com/arduino/go-paths-helper"
39
+ "github.com/pkg/errors"
40
40
"github.com/sirupsen/logrus"
41
41
"go.bug.st/downloader/v2"
42
42
)
@@ -179,14 +179,62 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequ
179
179
if err != nil {
180
180
return err
181
181
}
182
- d , err := lm .UpdateIndex (config )
182
+
183
+ if err := lm .IndexFile .Parent ().MkdirAll (); err != nil {
184
+ return err
185
+ }
186
+
187
+ // Create a temp dir to stage all downloads
188
+ tmp , err := paths .MkTempDir ("" , "library_index_download" )
183
189
if err != nil {
184
190
return err
185
191
}
186
- Download (d , "Updating index: library_index.json" , downloadCB )
187
- if d .Error () != nil {
188
- return d .Error ()
192
+ defer tmp .RemoveAll ()
193
+
194
+ // Download gzipped library_index
195
+ tmpIndexGz := tmp .Join ("library_index.json.gz" )
196
+ if d , err := downloader .DownloadWithConfig (tmpIndexGz .String (), librariesmanager .LibraryIndexGZURL .String (), * config , downloader .NoResume ); err == nil {
197
+ if err := Download (d , "Updating index: library_index.json.gz" , downloadCB ); err != nil {
198
+ return errors .Wrap (err , "downloading library_index.json.gz" )
199
+ }
200
+ } else {
201
+ return err
189
202
}
203
+
204
+ // Download signature
205
+ tmpSignature := tmp .Join ("library_index.json.sig" )
206
+ if d , err := downloader .DownloadWithConfig (tmpSignature .String (), librariesmanager .LibraryIndexSignature .String (), * config , downloader .NoResume ); err == nil {
207
+ if err := Download (d , "Updating index: library_index.json.sig" , downloadCB ); err != nil {
208
+ return errors .Wrap (err , "downloading library_index.json.sig" )
209
+ }
210
+ } else {
211
+ return err
212
+ }
213
+
214
+ // Extract the real library_index
215
+ tmpIndex := tmp .Join ("library_index.json" )
216
+ if err := paths .GUnzip (tmpIndexGz , tmpIndex ); err != nil {
217
+ return errors .Wrap (err , "unzipping library_index.json.gz" )
218
+ }
219
+
220
+ // Check signature
221
+ if ok , _ , err := security .VerifyArduinoDetachedSignature (tmpIndex , tmpSignature ); err != nil {
222
+ return errors .Wrap (err , "verifying signature" )
223
+ } else if ! ok {
224
+ return errors .New ("library_index.json has an invalid signature" )
225
+ }
226
+
227
+ // Copy extracted library_index and signature to final destination
228
+ lm .IndexFile .Remove ()
229
+ lm .IndexFileSignature .Remove ()
230
+ if err := tmpIndex .CopyTo (lm .IndexFile ); err != nil {
231
+ return errors .Wrap (err , "writing library_index.json" )
232
+ }
233
+ if err := tmpSignature .CopyTo (lm .IndexFileSignature ); err != nil {
234
+ return errors .Wrap (err , "writing library_index.json.sig" )
235
+ }
236
+
237
+ // Rescan libraries
190
238
if _ , err := Rescan (req .GetInstance ().GetId ()); err != nil {
191
239
return fmt .Errorf ("rescanning filesystem: %s" , err )
192
240
}
0 commit comments