/
zip.go
104 lines (88 loc) · 2.44 KB
/
zip.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package zip
import (
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/Dynatrace/dynatrace-operator/pkg/consts"
"github.com/Dynatrace/dynatrace-operator/pkg/injection/codemodule/installer/common"
"github.com/klauspost/compress/zip"
"github.com/pkg/errors"
"github.com/spf13/afero"
)
func (extractor OneAgentExtractor) ExtractZip(sourceFile afero.File, targetDir string) error {
extractor.cleanTempZipDir()
fs := extractor.fs
if sourceFile == nil {
return fmt.Errorf("file is nil")
}
fileInfo, err := sourceFile.Stat()
if err != nil {
log.Info("failed to get file info", "err", err)
return errors.WithStack(err)
}
reader, err := zip.NewReader(sourceFile, fileInfo.Size())
if err != nil {
log.Info("failed to create zip reader", "err", err)
return errors.WithStack(err)
}
extractDest := extractor.pathResolver.AgentTempUnzipRootDir()
if extractor.pathResolver.RootDir == consts.AgentBinDirMount {
extractDest = targetDir
}
err = extractFilesFromZip(fs, extractDest, reader)
if err != nil {
log.Info("failed to extract files from zip", "err", err)
return err
}
if extractDest != targetDir {
err := extractor.moveToTargetDir(targetDir)
if err != nil {
log.Info("failed to move file to final destination", "err", err)
return err
}
}
return nil
}
func extractFilesFromZip(fs afero.Fs, targetDir string, reader *zip.Reader) error {
if err := fs.MkdirAll(targetDir, common.MkDirFileMode); err != nil {
return errors.WithStack(err)
}
for _, file := range reader.File {
path := filepath.Join(targetDir, file.Name)
// Check for ZipSlip: https://snyk.io/research/zip-slip-vulnerability
if !strings.HasPrefix(path, filepath.Clean(targetDir)+string(os.PathSeparator)) {
return fmt.Errorf("illegal file path: %s", path)
}
mode := file.Mode()
if file.FileInfo().IsDir() {
err := fs.MkdirAll(path, mode)
if err != nil {
return errors.WithStack(err)
}
continue
}
if isAgentConfFile(file.Name) {
mode = common.ReadWriteAllFileMode
}
if err := fs.MkdirAll(filepath.Dir(path), mode); err != nil {
return errors.WithStack(err)
}
dstFile, err := fs.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
if err != nil {
return errors.WithStack(err)
}
srcFile, err := file.Open()
if err != nil {
return errors.WithStack(err)
}
_, err = io.Copy(dstFile, srcFile)
if err != nil {
return errors.WithStack(err)
}
dstFile.Close()
srcFile.Close()
}
return nil
}