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