feat: 实现白名单管理器以支持文件和进程的白名单检查
This commit is contained in:
parent
757d29c851
commit
2adbae8310
|
|
@ -0,0 +1,130 @@
|
|||
package whitelist
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/wuko233/sysmonitord/internal/config"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
mu sync.RWMutex
|
||||
official config.OfficialConfig
|
||||
user config.UserConfig
|
||||
mergedIgnore []string
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
return &Manager{
|
||||
official: config.OfficialConfig{
|
||||
WhitelistFiles: make(map[string][]string),
|
||||
},
|
||||
user: config.UserConfig{
|
||||
SupplementFiles: make(map[string][]string),
|
||||
SupplementProcesses: make(map[string]string),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) UpdateConfig(official config.OfficialConfig, user config.UserConfig) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.official = official
|
||||
m.user = user
|
||||
|
||||
m.mergedIgnore = append([]string{}, m.official.IgnoredPaths...)
|
||||
m.mergedIgnore = append(m.mergedIgnore, m.user.IgnoredPaths...)
|
||||
}
|
||||
|
||||
func (m *Manager) IsPathIgnored(path string) bool {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
path = filepath.Clean(path)
|
||||
for _, ignore := range m.mergedIgnore {
|
||||
if strings.HasPrefix(path, filepath.Clean(ignore)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CheckFileStatus 检查文件状态
|
||||
// 返回: isWhitelisted(是否在白名单), isValid(Hash是否匹配), err
|
||||
func (m *Manager) CheckFileStatus(path string) (bool, bool, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if m.IsPathIgnored((path)) {
|
||||
return true, true, nil
|
||||
}
|
||||
|
||||
hashes, exists := m.official.WhitelistFiles[path]
|
||||
if !exists {
|
||||
hashes, exists = m.user.SupplementFiles[path]
|
||||
}
|
||||
if !exists {
|
||||
return false, false, nil
|
||||
}
|
||||
|
||||
fileHash, err := CalculateFileHash(path)
|
||||
if err != nil {
|
||||
return true, false, fmt.Errorf("计算文件哈希失败: %v", err)
|
||||
}
|
||||
|
||||
for _, h := range hashes {
|
||||
if strings.EqualFold(h, fmt.Sprintf("%v", fileHash)) {
|
||||
return true, true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, false, nil
|
||||
}
|
||||
|
||||
func CalculateFileHash(filePath string) (string, error) {
|
||||
file, err := os.Open(filePath)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
hash := sha256.New()
|
||||
if _, err := io.Copy(hash, file); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(hash.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func (m *Manager) IsProcessAllowed(procName string, cmdLine string) bool {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
for _, p := range m.official.WhitelistProcesses {
|
||||
if p == procName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := m.user.SupplementProcesses[procName]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Manager) GetAuditServerUrl() string {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
return m.user.AuditServerUrl
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user