1616package resources
1717
1818import (
19+ "context"
1920 "net/url"
2021 "path"
2122 "strings"
@@ -25,6 +26,8 @@ import (
2526 "github.com/arduino/arduino-cli/arduino/security"
2627 rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
2728 "github.com/arduino/go-paths-helper"
29+ "github.com/codeclysm/extract/v3"
30+ "github.com/sirupsen/logrus"
2831 "go.bug.st/downloader/v2"
2932)
3033
@@ -56,8 +59,43 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
5659 return & arduino.FailedDownloadError {Message : tr ("Error downloading index '%s'" , res .URL ), Cause : err }
5760 }
5861
62+ var signaturePath , tmpSignaturePath * paths.Path
63+ hasSignature := false
64+
5965 // Expand the index if it is compressed
60- if strings .HasSuffix (indexFileName , ".gz" ) {
66+ if strings .HasSuffix (indexFileName , ".tar.bz2" ) {
67+ indexFileName = strings .TrimSuffix (indexFileName , ".tar.bz2" ) + ".json" // == package_index.json
68+ signatureFileName := indexFileName + ".sig"
69+ signaturePath = destDir .Join (signatureFileName )
70+
71+ // .tar.bz2 archive may contain both index and signature
72+
73+ // Extract archive in a tmp/archive subdirectory
74+ f , err := tmpIndexPath .Open ()
75+ if err != nil {
76+ return & arduino.PermissionDeniedError {Message : tr ("Error opening %s" , tmpIndexPath ), Cause : err }
77+ }
78+ defer f .Close ()
79+ tmpArchivePath := tmp .Join ("archive" )
80+ _ = tmpArchivePath .MkdirAll ()
81+ if err := extract .Bz2 (context .Background (), f , tmpArchivePath .String (), nil ); err != nil {
82+ return & arduino.PermissionDeniedError {Message : tr ("Error extracting %s" , tmpIndexPath ), Cause : err }
83+ }
84+
85+ // Look for index.json
86+ tmpIndexPath = tmpArchivePath .Join (indexFileName )
87+ if ! tmpIndexPath .Exist () {
88+ return & arduino.NotFoundError {Message : tr ("Invalid archive: file %{1}s not found in archive %{2}s" , indexFileName , tmpArchivePath .Base ())}
89+ }
90+
91+ // Look for signature
92+ if t := tmpArchivePath .Join (signatureFileName ); t .Exist () {
93+ tmpSignaturePath = t
94+ hasSignature = true
95+ } else {
96+ logrus .Infof ("No signature %s found in package index archive %s" , signatureFileName , tmpArchivePath .Base ())
97+ }
98+ } else if strings .HasSuffix (indexFileName , ".gz" ) {
6199 indexFileName = strings .TrimSuffix (indexFileName , ".gz" ) // == package_index.json
62100 tmpUnzippedIndexPath := tmp .Join (indexFileName )
63101 if err := paths .GUnzip (tmpIndexPath , tmpUnzippedIndexPath ); err != nil {
@@ -67,7 +105,6 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
67105 }
68106
69107 // Check the signature if needed
70- var signaturePath , tmpSignaturePath * paths.Path
71108 if res .SignatureURL != nil {
72109 // Compose signature URL
73110 signatureFileName := path .Base (res .SignatureURL .Path )
@@ -79,6 +116,10 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
79116 return & arduino.FailedDownloadError {Message : tr ("Error downloading index signature '%s'" , res .SignatureURL ), Cause : err }
80117 }
81118
119+ hasSignature = true
120+ }
121+
122+ if hasSignature {
82123 // Check signature...
83124 if valid , _ , err := security .VerifyArduinoDetachedSignature (tmpIndexPath , tmpSignaturePath ); err != nil {
84125 return & arduino.PermissionDeniedError {Message : tr ("Error verifying signature" ), Cause : err }
@@ -109,12 +150,12 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
109150 if err := tmpIndexPath .CopyTo (indexPath ); err != nil {
110151 return & arduino.PermissionDeniedError {Message : tr ("Error saving downloaded index" ), Cause : err }
111152 }
112- if res . SignatureURL != nil {
153+ if hasSignature {
113154 if err := tmpSignaturePath .CopyTo (signaturePath ); err != nil {
114155 return & arduino.PermissionDeniedError {Message : tr ("Error saving downloaded index signature" ), Cause : err }
115156 }
116157 }
117- oldIndex .Remove ()
118- oldSignature .Remove ()
158+ _ = oldIndex .Remove ()
159+ _ = oldSignature .Remove ()
119160 return nil
120161}
0 commit comments