forked from samwafgo/SamWaf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wafinit.go
148 lines (130 loc) · 4.41 KB
/
wafinit.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package wafinit
import (
"SamWaf/common/zlog"
"embed"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
// 版本文件路径在内嵌资源中
const versionFilePath = "exedata/owasp/version"
// CheckAndReleaseDataset 检查目标目录的版本,并根据条件决定是否释放数据集
func CheckAndReleaseDataset(owaspAssets embed.FS, targetDir string) error {
innerLogName := "CheckOWASPRelease"
zlog.Info(innerLogName, "检测OWASP数据集合")
// 设置 lock.txt 文件路径
lockFilePath := filepath.Join(targetDir, "lock.txt")
// 检查目标目录是否已存在
if _, err := os.Stat(targetDir); os.IsNotExist(err) {
// 目录不存在,创建目录
err := os.MkdirAll(targetDir, 0755)
if err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
zlog.Info(innerLogName, "OWASP Directory created:"+targetDir)
}
// 检查 lock.txt 是否存在
if _, err := os.Stat(lockFilePath); !os.IsNotExist(err) {
// lock.txt 存在,跳过释放
zlog.Info(innerLogName, "Lock file exists, skipping release of the dataset")
return nil
}
// 获取当前版本号,从内嵌的版本文件中读取
currentVersion, err := getCurrentVersion(owaspAssets)
if err != nil {
return fmt.Errorf("error reading current version: %w", err)
}
// 检查版本号文件是否存在以及版本号
var targetVersion string
versionFilePath := filepath.Join(targetDir, "version")
if _, err := os.Stat(versionFilePath); os.IsNotExist(err) {
// version 文件不存在,认为是第一次运行,释放文件
targetVersion = ""
} else {
// 读取版本号文件内容
data, err := ioutil.ReadFile(versionFilePath)
if err != nil {
zlog.Info(innerLogName, "Error reading version file:", err.Error())
}
targetVersion = strings.TrimSpace(string(data))
}
// 如果版本号不存在,或者目标版本号较旧,则释放文件
if targetVersion == "" || compareVersions(targetVersion, currentVersion) < 0 {
// 释放文件
err := ReleaseFiles(owaspAssets, "exedata/owasp", targetDir)
if err != nil {
return fmt.Errorf("error releasing files: %w", err)
}
// 释放后更新版本号
err = ioutil.WriteFile(versionFilePath, []byte(currentVersion), 0644)
if err != nil {
return fmt.Errorf("error writing version file: %w", err)
}
zlog.Info(innerLogName, "数据集已更新.")
} else {
// 版本号是最新的,不需要释放
zlog.Info(innerLogName, "版本号是最新的,不需要释放.")
}
return nil
}
// 获取当前版本号,从内嵌的版本文件中读取
func getCurrentVersion(owaspAssets embed.FS) (string, error) {
data, err := owaspAssets.ReadFile(versionFilePath)
if err != nil {
return "", fmt.Errorf("failed to read version file from embedded assets: %w", err)
}
return strings.TrimSpace(string(data)), nil
}
// 比较版本号(假设版本号格式为 "X.Y.Z")
func compareVersions(version1, version2 string) int {
v1 := strings.Split(version1, ".")
v2 := strings.Split(version2, ".")
for i := 0; i < 3; i++ {
if v1[i] < v2[i] {
return -1
} else if v1[i] > v2[i] {
return 1
}
}
return 0
}
// ReleaseFiles 释放嵌入的文件到目标目录
func ReleaseFiles(owaspAssets embed.FS, srcPath, destPath string) error {
// 检查目标文件夹是否存在,不存在则创建
innerLogName := "ReleaseFiles"
if err := os.MkdirAll(destPath, os.ModePerm); err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
// 遍历嵌入的文件
entries, err := owaspAssets.ReadDir(srcPath)
if err != nil {
return fmt.Errorf("failed to read embedded directory: %w", err)
}
for _, entry := range entries {
source := filepath.Join(srcPath, entry.Name())
destination := filepath.Join(destPath, entry.Name())
// 确保路径使用正斜杠
source = strings.ReplaceAll(source, "\\", "/")
destination = strings.ReplaceAll(destination, "\\", "/")
// 如果是目录,递归提取
if entry.IsDir() {
if err := ReleaseFiles(owaspAssets, source, destination); err != nil {
return err
}
} else {
// 如果是文件,检查是否存在,如果不存在则写入
data, err := owaspAssets.ReadFile(source)
if err != nil {
return fmt.Errorf("failed to read file from embed: %w", err)
}
// 写入文件
if err := os.WriteFile(destination, data, 0644); err != nil {
return fmt.Errorf("failed to write file: %w", err)
}
zlog.Info(innerLogName, "OWASP Extracted:"+destination)
}
}
return nil
}