@@ -17,7 +17,6 @@ package commands
1717
1818import (
1919 "context"
20- "errors"
2120 "fmt"
2221 "io/ioutil"
2322 "net/url"
@@ -37,6 +36,7 @@ import (
3736 "github.com/arduino/arduino-cli/configuration"
3837 rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
3938 paths "github.com/arduino/go-paths-helper"
39+ "github.com/pkg/errors"
4040 "github.com/sirupsen/logrus"
4141 "go.bug.st/downloader/v2"
4242)
@@ -179,14 +179,62 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequ
179179 if err != nil {
180180 return err
181181 }
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" )
183189 if err != nil {
184190 return err
185191 }
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
189202 }
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
190238 if _ , err := Rescan (req .GetInstance ().GetId ()); err != nil {
191239 return fmt .Errorf ("rescanning filesystem: %s" , err )
192240 }
0 commit comments