16
16
package resources
17
17
18
18
import (
19
+ "context"
19
20
"net/url"
20
21
"path"
21
22
"strings"
@@ -25,6 +26,8 @@ import (
25
26
"github.com/arduino/arduino-cli/arduino/security"
26
27
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
27
28
"github.com/arduino/go-paths-helper"
29
+ "github.com/codeclysm/extract/v3"
30
+ "github.com/sirupsen/logrus"
28
31
"go.bug.st/downloader/v2"
29
32
)
30
33
@@ -56,8 +59,43 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
56
59
return & arduino.FailedDownloadError {Message : tr ("Error downloading index '%s'" , res .URL ), Cause : err }
57
60
}
58
61
62
+ var signaturePath , tmpSignaturePath * paths.Path
63
+ hasSignature := false
64
+
59
65
// 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" ) {
61
99
indexFileName = strings .TrimSuffix (indexFileName , ".gz" ) // == package_index.json
62
100
tmpUnzippedIndexPath := tmp .Join (indexFileName )
63
101
if err := paths .GUnzip (tmpIndexPath , tmpUnzippedIndexPath ); err != nil {
@@ -67,7 +105,6 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
67
105
}
68
106
69
107
// Check the signature if needed
70
- var signaturePath , tmpSignaturePath * paths.Path
71
108
if res .SignatureURL != nil {
72
109
// Compose signature URL
73
110
signatureFileName := path .Base (res .SignatureURL .Path )
@@ -79,6 +116,10 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
79
116
return & arduino.FailedDownloadError {Message : tr ("Error downloading index signature '%s'" , res .SignatureURL ), Cause : err }
80
117
}
81
118
119
+ hasSignature = true
120
+ }
121
+
122
+ if hasSignature {
82
123
// Check signature...
83
124
if valid , _ , err := security .VerifyArduinoDetachedSignature (tmpIndexPath , tmpSignaturePath ); err != nil {
84
125
return & arduino.PermissionDeniedError {Message : tr ("Error verifying signature" ), Cause : err }
@@ -109,12 +150,12 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP
109
150
if err := tmpIndexPath .CopyTo (indexPath ); err != nil {
110
151
return & arduino.PermissionDeniedError {Message : tr ("Error saving downloaded index" ), Cause : err }
111
152
}
112
- if res . SignatureURL != nil {
153
+ if hasSignature {
113
154
if err := tmpSignaturePath .CopyTo (signaturePath ); err != nil {
114
155
return & arduino.PermissionDeniedError {Message : tr ("Error saving downloaded index signature" ), Cause : err }
115
156
}
116
157
}
117
- oldIndex .Remove ()
118
- oldSignature .Remove ()
158
+ _ = oldIndex .Remove ()
159
+ _ = oldSignature .Remove ()
119
160
return nil
120
161
}
0 commit comments