YAML config, and log rotation

main
Robert 7 months ago
parent dc68aca96a
commit 9c45c054fd
  1. 48
      README.md
  2. 14
      config.json.example
  3. 25
      config.yaml.example
  4. 2
      core/alert/alert.go
  5. 59
      core/configure/configure.go
  6. 2
      core/hasher/hasher.go
  7. 2
      core/monitor_running_bins/monitor_running_bins.go
  8. 4
      core/new_file_monitor/new_file_monitor.go
  9. 130
      core/rotating_logger/rotating_logger.go
  10. 2
      core/scanner/scanner.go
  11. 12
      core/sys_database/sys_database.go
  12. 6
      docs/Logs.md
  13. 6
      docs/OpenSnitch.md
  14. 59
      execguard.go
  15. 2
      go.mod
  16. 4
      go.sum
  17. 14
      install.sh

@ -33,23 +33,33 @@ It is in Leaning mode... All program will run as normal.
* You should monitor the output of the log file: * You should monitor the output of the log file:
- tail -F /var/log/execguard.log - tail -F /var/log/execguard.log
## /etc/execgaurd/config.json ## /etc/execgaurd/config.yaml
scan_interval is the number of minutes to delay before scanning the protected_dirs for executables that are not allowed to run, it will chmod -x those programs. If 0, disables the scan for executables to remove the executution (x) bit. DO NOT ADD system bin paths to the Protected Dirs!!! As your system will fail to Boot!! skip_dirs are directories to skip inside of the protected_dirs. alert_email is where to send alerts besides the /var/log/execgaurd.log file. If the alert_email is an empty string, that will not send any emails... hash_encryption takes one of the following: none, xor, or xxtea. Passphrase is used on xor or xxtea to provide security against people injecting hashes into the database to make a bad program run. hash_type is either sha256, or sha512. Sha512 is better for security and sha256 is better on perforance, maybe...Be sure to UPDATE your downloads folders, to YOURS!!! scan_interval is the number of minutes to delay before scanning the protected_dirs for executables that are not allowed to run, it will chmod -x those programs. If 0, disables the scan for executables to remove the executution (x) bit. DO NOT ADD system bin paths to the Protected Dirs!!! As your system will fail to Boot!! skip_dirs are directories to skip inside of the protected_dirs. alert_email is where to send alerts besides the /var/log/execgaurd.log file. If the alert_email is an empty string, that will not send any emails... hash_encryption takes one of the following: none, xor, or xxtea. Passphrase is used on xor or xxtea to provide security against people injecting hashes into the database to make a bad program run. hash_type is either sha256, or sha512. Sha512 is better for security and sha256 is better on perforance, maybe...Be sure to UPDATE your downloads folders, to YOURS!!!
``` ```
{ logging:
"db_file": "/etc/execguard/system.db", filePath: "/var/log/execguard.log" # Main Log file to watch
"log_file": "/var/log/execguard.log", maxSizeMB: 10 # Max log size in megabytes
"mail_prog": "/usr/bin/mail", backups: 5 # Number of backup logs to keep
"scanner_prog": "/usr/bin/clamscan", compressBackups: true # Whether to gzip old logs
"downloads": ["/home/EXAMPLEUSER1_CHANGEME/Downloads", "/home/USER2_IF_THEY_EXISTS/Downloads"], timestampFormat: "2006-01-02T15:04:05" # Go time format
"scan_interval": 0,
"protected_dirs": ["/home/EXAMPLEUSER_CHANGEME/Documents"], db_file: "/etc/execguard/system.db" # Allowed programs DB
"skip_dirs": [".cache",".git"], mail_prog: "/usr/bin/mail" # Mail Util
"alert_email": "root@localhost" scanner_prog: "/usr/bin/clamscan" # AV Scanner
"passphrase": "cdzTE1Gk6/VuDlnU",
"hash_encryption": "xxtea", downloads: # folders to Scan for Viruses
"hash_type": "sha512" - "/home/EXAMPLEUSER1/Downloads"
} - "/home/exampleUser2/Downloads"
scan_interval: 90 # Minutes before next Exec bit Scan
protected_dirs: # Folders that should Never have an Exec Bit Enabled!
- "/home/EXAMPLEUSER1/Documents"
skip_dirs: [".cache",".git"]
alert_email: "" # root@localhost - Admin local Mail
passphrase: "cdzTE1Gk6/VuDlnU" # Hash change protection
hash_encryption: "xxtea" # Encryption xxtea, xor, or none
hash_type: "sha512" # Hashing Algo. sha 256, or sha 512
``` ```
## FYI - To get root mail from Alerts ## FYI - To get root mail from Alerts
``` ```
@ -103,12 +113,11 @@ If you have not allowed all the things needed for your system, it will HANG-UP a
sudo systemctl disable --now execguard@init sudo systemctl disable --now execguard@init
sudo systemctl execguard@init status sudo systemctl execguard@init status
sudo systemctl enable --now execguard@enforce startExecguard enforce
sudo systemctl execguard@enforce status
``` ```
Reboot. Reboot.
# Migrations ONLY after changes on config.json # Migrations ONLY after changes on config.yaml
Note: It's best to set the config.json before Installing....! However, you can do it... Note: It's best to set the config.yaml before Installing....! However, you can do it...
Changes made to passwords, hashes on system with existing data on system.db database...need to be migrated. Changes made to passwords, hashes on system with existing data on system.db database...need to be migrated.
``` ```
./stopExecguard.sh ./stopExecguard.sh
@ -133,4 +142,5 @@ sudo rm -rf /var/lib/clamav/quarantine/*
- [x] Auto scan new files in Downloads. - [x] Auto scan new files in Downloads.
- [x] Watch/Monitor Logs via: $ tail -F /var/log/execguard.log - [x] Watch/Monitor Logs via: $ tail -F /var/log/execguard.log
- [x] Use custom SQLite3 Database file: Default is /etc/execguard/system.db - [x] Use custom SQLite3 Database file: Default is /etc/execguard/system.db
- [x] Log Rotation
- [ ] Debug more...this is in Alpha. - [ ] Debug more...this is in Alpha.

@ -1,14 +0,0 @@
{
"db_file": "/etc/execguard/system.db",
"log_file": "/var/log/execguard.log",
"mail_prog": "/usr/bin/mail",
"scanner_prog": "/usr/bin/clamscan",
"downloads": ["/home/EXAMPLEUSER1/Downloads", "/home/exampleUser2/Downloads"],
"scan_interval": 90,
"protected_dirs": ["/home/EXAMPLEUSER1/Documents"],
"skip_dirs": [".cache",".git"],
"alert_email": "",
"passphrase": "cdzTE1Gk6/VuDlnU",
"hash_encryption": "xxtea",
"hash_type": "sha512"
}

@ -0,0 +1,25 @@
logging:
filePath: "/var/log/execguard.log"
maxSizeMB: 10 # Max log size in megabytes
backups: 5 # Number of backup logs to keep
compressBackups: true # Whether to gzip old logs
timestampFormat: "2006-01-02T15:04:05" # Go time format
db_file: "/etc/execguard/system.db" # Allowed programs DB
mail_prog: "/usr/bin/mail" # Mail Util
scanner_prog: "/usr/bin/clamscan" # AV Scanner
downloads: # folders to Scan for Viruses
- "/home/EXAMPLEUSER1/Downloads"
- "/home/exampleUser2/Downloads"
scan_interval: 90 # Minutes before next Exec bit Scan
protected_dirs: # Folders that should Never have an Exec Bit Enabled!
- "/home/EXAMPLEUSER1/Documents"
skip_dirs: [".cache",".git"]
alert_email: "" # root@localhost - Admin local Mail
passphrase: "cdzTE1Gk6/VuDlnU" # Hash change protection
hash_encryption: "xxtea" # Encryption xxtea, xor, or none
hash_type: "sha512" # Hashing Algo. sha 256, or sha 512

@ -28,7 +28,7 @@ func SetGlobalMail(m string) {
mailPath = m mailPath = m
} }
func SendAlert(message string, db *sql.DB, log log.Logger) { func SendAlert(message string, db *sql.DB, log *log.Logger) {
if config.AlertEmail == "" { if config.AlertEmail == "" {
return return
} }

@ -6,32 +6,59 @@ package configure
import ( import (
"os" "os"
"encoding/json" "gopkg.in/yaml.v3"
"fmt"
) )
const (
MaxSizeMB = 10
Backups = 5
tsFmt = "2006-01-02 15:04:05"
)
type LoggingConfig struct {
FilePath string `yaml:"filePath"`
MaxSizeMB int `yaml:"maxSizeMB"`
Backups int `yaml:"backups"`
CompressBackups bool `yaml:"compressBackups"`
TimestampFormat string `yaml:"timestampFormat"`
}
type Config struct { type Config struct {
DbFile string `json:"db_file"` // optional DB File Logging LoggingConfig `yaml:"logging"`
LogFile string `json:"log_file"` // optional Log File DbFile string `yaml:"db_file"` // optional DB File
MailProg string `json:"mail_prog"` // optional Mail Program MailProg string `yaml:"mail_prog"` // optional Mail Program
ScannerProg string `json:"scanner_prog"` // optional Virus Scanner Program ScannerProg string `yaml:"scanner_prog"` // optional Virus Scanner Program
ProtectedDirs []string `json:"protected_dirs"` ProtectedDirs []string `yaml:"protected_dirs"`
Downloads []string `josn:"downloads"` Downloads []string `yaml:"downloads"`
AlertEmail string `json:"alert_email"` // optional root@localhost AlertEmail string `yaml:"alert_email"` // optional root@localhost
SkipDirs []string `json:"skip_dirs"` SkipDirs []string `yaml:"skip_dirs"`
ScanInterval int `json:"scan_interval"` // in minutes, 0 disables scan ScanInterval int `yaml:"scan_interval"` // in minutes, 0 disables scan
Passphrase string `json:"passphrase"` // optional hash encryption key Passphrase string `yaml:"passphrase"` // optional hash encryption key
HashEncryption string `json:"hash_encryption"` // "none", "xor", or "xxtea" HashEncryption string `yaml:"hash_encryption"` // "none", "xor", or "xxtea"
HashType string `json:"hash_type"` // "sha256" or "sha512" HashType string `yaml:"hash_type"` // "sha256" or "sha512"
} }
func LoadConfig(configFile string) (*Config, error) { func LoadConfig(configFile string, logFile string) (*Config, error) {
data, err := os.ReadFile(configFile) data, err := os.ReadFile(configFile)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var cfg Config var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil { if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, err return nil, fmt.Errorf("failed to parse config: %v", err)
}
if cfg.Logging.FilePath == "" {
cfg.Logging.FilePath = logFile
}
if cfg.Logging.MaxSizeMB == 0 {
cfg.Logging.MaxSizeMB = MaxSizeMB
}
if cfg.Logging.Backups == 0 {
cfg.Logging.Backups = Backups
}
if cfg.Logging.TimestampFormat == "" {
cfg.Logging.TimestampFormat = tsFmt
} }
return &cfg, nil return &cfg, nil
} }

@ -42,7 +42,7 @@ func normalizeXXTEAKey(key []byte) []byte {
} }
} }
func ComputeHash(path string, log log.Logger) string { func ComputeHash(path string, log *log.Logger) string {
data, err := os.ReadFile(path) data, err := os.ReadFile(path)
if err != nil { if err != nil {
return "" return ""

@ -44,7 +44,7 @@ func SetGlobalConfig(c configure.Config) {
config = c config = c
} }
func MonitorExecutions(db *sql.DB, log log.Logger, mailPath string) error { func MonitorExecutions(db *sql.DB, log *log.Logger, mailPath string) error {
fd, err := unix.FanotifyInit(unix.FAN_CLOEXEC|unix.FAN_CLASS_CONTENT, unix.O_RDONLY|unix.O_LARGEFILE) fd, err := unix.FanotifyInit(unix.FAN_CLOEXEC|unix.FAN_CLASS_CONTENT, unix.O_RDONLY|unix.O_LARGEFILE)
if err != nil { if err != nil {
return fmt.Errorf("fanotify init failed: %w", err) return fmt.Errorf("fanotify init failed: %w", err)

@ -24,7 +24,7 @@ var (
alertCache sync.Map alertCache sync.Map
) )
func Monitor_new_files(dirs []string, db *sql.DB, log log.Logger, scannerPath string) { func Monitor_new_files(dirs []string, db *sql.DB, log *log.Logger, scannerPath string) {
// Create new watcher // Create new watcher
watcher, err := fsnotify.NewWatcher() watcher, err := fsnotify.NewWatcher()
if err != nil { if err != nil {
@ -87,7 +87,7 @@ func Monitor_new_files(dirs []string, db *sql.DB, log log.Logger, scannerPath st
select {} select {}
} }
func scanFile(filePath string, scannerPath string, db *sql.DB, log log.Logger) { func scanFile(filePath string, scannerPath string, db *sql.DB, log *log.Logger) {
time.Sleep(time.Duration(300) * time.Millisecond) time.Sleep(time.Duration(300) * time.Millisecond)
// Get just the filename for cleaner output // Get just the filename for cleaner output
fileName := filepath.Base(filePath) fileName := filepath.Base(filePath)

@ -0,0 +1,130 @@
package rotating_logger
import (
"execguard/core/configure"
"compress/gzip"
"os"
"fmt"
"io"
"strings"
"path/filepath"
"sync"
)
type RotatingLogger struct {
config configure.LoggingConfig
currentFile *os.File
mu sync.Mutex
}
func NewRotatingLogger(config configure.LoggingConfig) (*RotatingLogger, error) {
rl := &RotatingLogger{config: config}
if err := rl.openFile(); err != nil {
return nil, err
}
return rl, nil
}
func (rl *RotatingLogger) openFile() error {
if err := os.MkdirAll(filepath.Dir(rl.config.FilePath), 0755); err != nil {
return fmt.Errorf("failed to create log directory: %v", err)
}
file, err := os.OpenFile(rl.config.FilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0640)
if err != nil {
return fmt.Errorf("failed to open log file: %v", err)
}
rl.currentFile = file
return nil
}
func (rl *RotatingLogger) rotate() error {
rl.mu.Lock()
defer rl.mu.Unlock()
if err := rl.currentFile.Close(); err != nil {
return err
}
for i := rl.config.Backups - 1; i >= 0; i-- {
src := rl.getBackupName(i)
if _, err := os.Stat(src); err == nil {
dst := rl.getBackupName(i + 1)
if i+1 >= rl.config.Backups {
os.Remove(dst)
} else {
if rl.config.CompressBackups && !strings.HasSuffix(src, ".gz") {
if err := rl.compressFile(src); err != nil {
return err
}
src += ".gz"
dst += ".gz"
}
os.Rename(src, dst)
}
}
}
if err := os.Rename(rl.config.FilePath, rl.getBackupName(0)); err != nil {
return err
}
return rl.openFile()
}
func (rl *RotatingLogger) compressFile(src string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(src + ".gz")
if err != nil {
return err
}
defer out.Close()
gz := gzip.NewWriter(out)
defer gz.Close()
if _, err = io.Copy(gz, in); err != nil {
return err
}
return os.Remove(src)
}
func (rl *RotatingLogger) getBackupName(index int) string {
if index == 0 {
return rl.config.FilePath + ".1"
}
return fmt.Sprintf("%s.%d", rl.config.FilePath, index+1)
}
func (rl *RotatingLogger) needsRotation() (bool, error) {
info, err := rl.currentFile.Stat()
if err != nil {
return false, err
}
return info.Size() >= int64(rl.config.MaxSizeMB*1024*1024), nil
}
func (rl *RotatingLogger) Write(p []byte) (n int, err error) {
if rotate, err := rl.needsRotation(); rotate && err == nil {
if err := rl.rotate(); err != nil {
return 0, err
}
}
rl.mu.Lock()
defer rl.mu.Unlock()
return rl.currentFile.Write(p)
}
func (rl *RotatingLogger) Close() error {
rl.mu.Lock()
defer rl.mu.Unlock()
return rl.currentFile.Close()
}

@ -41,7 +41,7 @@ func SetGlobalConfig(c configure.Config) {
config = c config = c
} }
func PeriodicScan(dirs []string, db *sql.DB, log log.Logger, mailPath string, scanInterval int) { func PeriodicScan(dirs []string, db *sql.DB, log *log.Logger, mailPath string, scanInterval int) {
skipSet := make(map[string]struct{}) skipSet := make(map[string]struct{})
for _, skip := range config.SkipDirs { for _, skip := range config.SkipDirs {
if abs, err := filepath.Abs(skip); err == nil { if abs, err := filepath.Abs(skip); err == nil {

@ -31,7 +31,7 @@ func SetModes(mode bool, file string, update string, migrate bool) {
migrateMode = migrate migrateMode = migrate
} }
func CreateTable(db *sql.DB, log log.Logger) { func CreateTable(db *sql.DB, log *log.Logger) {
query := `CREATE TABLE IF NOT EXISTS allowed ( query := `CREATE TABLE IF NOT EXISTS allowed (
path TEXT PRIMARY KEY, path TEXT PRIMARY KEY,
hash TEXT hash TEXT
@ -43,7 +43,7 @@ func CreateTable(db *sql.DB, log log.Logger) {
} }
} }
func readFile(db *sql.DB, log log.Logger, input *os.File) { func readFile(db *sql.DB, log *log.Logger, input *os.File) {
defer input.Close() defer input.Close()
scanner := bufio.NewScanner(input) scanner := bufio.NewScanner(input)
@ -60,7 +60,7 @@ func readFile(db *sql.DB, log log.Logger, input *os.File) {
} }
} }
func RunInit(db *sql.DB, log log.Logger, path string) { func RunInit(db *sql.DB, log *log.Logger, path string) {
input, err := os.Open(path) input, err := os.Open(path)
if err != nil { if err != nil {
log.Fatalf("Failed to open temp file: %v", err) log.Fatalf("Failed to open temp file: %v", err)
@ -68,7 +68,7 @@ func RunInit(db *sql.DB, log log.Logger, path string) {
readFile(db, log, input) readFile(db, log, input)
} }
func RunMigration(db *sql.DB, log log.Logger) { func RunMigration(db *sql.DB, log *log.Logger) {
tempFile := "Migrate" tempFile := "Migrate"
f, err := os.CreateTemp("", tempFile) f, err := os.CreateTemp("", tempFile)
@ -99,7 +99,7 @@ func RunMigration(db *sql.DB, log log.Logger) {
readFile(db, log, f) readFile(db, log, f)
} }
func IsAllowed(db *sql.DB, log log.Logger, path string) bool { func IsAllowed(db *sql.DB, log *log.Logger, path string) bool {
var storedHash string var storedHash string
hash := hasher.ComputeHash(path, log) hash := hasher.ComputeHash(path, log)
if hash == "" { if hash == "" {
@ -109,7 +109,7 @@ func IsAllowed(db *sql.DB, log log.Logger, path string) bool {
return err == nil && storedHash == hash return err == nil && storedHash == hash
} }
func AddToAllowed(db *sql.DB, log log.Logger, path string) { func AddToAllowed(db *sql.DB, log *log.Logger, path string) {
dbMutex.Lock() dbMutex.Lock()
defer dbMutex.Unlock() defer dbMutex.Unlock()

@ -0,0 +1,6 @@
# Logs
```
journalctl -t execsans --facility=local0
sudo tail -F /var/log/execguard.log
```

@ -0,0 +1,6 @@
# OpenSnitch Firewall
## This is an powerfull but annoying prog
It will default to block outbound connections but asks before...doing so. This is not a requierment, just a cool program.
```
sudo apt install opensnitch
```

@ -7,6 +7,7 @@ package main
import ( import (
"execguard/core/alert" "execguard/core/alert"
"execguard/core/configure" "execguard/core/configure"
"execguard/core/rotating_logger"
"execguard/core/hasher" "execguard/core/hasher"
"execguard/core/make_key" "execguard/core/make_key"
"execguard/core/monitor_running_bins" "execguard/core/monitor_running_bins"
@ -18,13 +19,14 @@ import (
"log" "log"
"strings" "strings"
"os" "os"
"fmt" "fmt"
"time"
"path/filepath" "path/filepath"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
) )
const ( const (
configFileDefault = "/etc/execguard/config.json" configFileDefault = "/etc/execguard/config.yaml"
dbFileDefault = "/etc/execguard/system.db" dbFileDefault = "/etc/execguard/system.db"
logFileDefault = "/var/log/execguard.log" logFileDefault = "/var/log/execguard.log"
mailPathDefault = "/usr/bin/mail" mailPathDefault = "/usr/bin/mail"
@ -60,7 +62,6 @@ var (
func main() { func main() {
var err error var err error
var log log.Logger
flag.IntVar(&scanIntervalFlag, "scanDelayMinutes", 99, "0 disables scanner") flag.IntVar(&scanIntervalFlag, "scanDelayMinutes", 99, "0 disables scanner")
flag.StringVar(&downloadsFlag, "downloads", "none", "use specified Downloads folders comma-seperated list") flag.StringVar(&downloadsFlag, "downloads", "none", "use specified Downloads folders comma-seperated list")
@ -100,7 +101,13 @@ func main() {
configFile = configFileDefault configFile = configFileDefault
} }
config, err := configure.LoadConfig(configFile) if logFlag != "" {
logFile = logFlag
} else {
logFile = logFileDefault
}
config, err := configure.LoadConfig(configFile, logFile)
if err != nil { if err != nil {
fmt.Printf("Error loading config: %v", err) fmt.Printf("Error loading config: %v", err)
os.Exit(3) // Exit with status code 3 os.Exit(3) // Exit with status code 3
@ -120,14 +127,6 @@ func main() {
dbFile = dbFileDefault dbFile = dbFileDefault
} }
if logFlag != "" {
logFile = logFlag
} else if config.LogFile != "" {
logFile = config.LogFile
} else {
logFile = logFileDefault
}
if mailFlag != "" { if mailFlag != "" {
mailPath = mailFlag mailPath = mailFlag
} else if config.MailProg != "" { } else if config.MailProg != "" {
@ -166,45 +165,47 @@ func main() {
dirs = downloadsDefault dirs = downloadsDefault
} }
logf, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) rl, err := rotating_logger.NewRotatingLogger(config.Logging)
if err != nil { if err != nil {
log.Fatalf("Error opening log file: %v", err) fmt.Printf("Failed to initialize logger: %v", err)
} }
defer logf.Close() defer rl.Close()
log.SetOutput(logf)
logger := log.New(rl, "", 0)
logger.SetPrefix(fmt.Sprintf("[%s] ", time.Now().Format(config.Logging.TimestampFormat)))
db, err := sql.Open("sqlite3", dbFile) db, err := sql.Open("sqlite3", dbFile)
if err != nil { if err != nil {
log.Fatalf("Error opening database: %v", err) logger.Fatalf("Error opening database: %v", err)
os.Exit(2) // Exit with status code 2 os.Exit(2) // Exit with status code 2
} }
defer db.Close() defer db.Close()
sys_database.CreateTable(db, log) sys_database.CreateTable(db, logger)
if initFile != "" { if initFile != "" {
absPath, err := filepath.Abs(initFile) absPath, err := filepath.Abs(initFile)
if err != nil { if err != nil {
log.Fatalf("Invalid init file path: %v", err) logger.Fatalf("Invalid init file path: %v", err)
os.Exit(1) // Exit with status code 1 os.Exit(1) // Exit with status code 1
} }
sys_database.RunInit(db, log, absPath) sys_database.RunInit(db, logger, absPath)
return return
} }
if updateFile != "" { if updateFile != "" {
absPath, err := filepath.Abs(updateFile) absPath, err := filepath.Abs(updateFile)
if err != nil { if err != nil {
log.Fatalf("Invalid update file path: %v", err) logger.Fatalf("Invalid update file path: %v", err)
os.Exit(1) // Exit with status code 1 os.Exit(1) // Exit with status code 1
} }
sys_database.AddToAllowed(db, log, absPath) sys_database.AddToAllowed(db, logger, absPath)
log.Printf("Added to allowed list: %s", absPath) logger.Printf("Added to allowed list: %s", absPath)
return return
} }
if migrateMode { if migrateMode {
sys_database.RunMigration(db, log) sys_database.RunMigration(db, logger)
return return
} }
@ -212,19 +213,19 @@ func main() {
go func() { go func() {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
log.Printf("Recovered from scan panic: %v", r) logger.Printf("Recovered from scan panic: %v", r)
} }
}() }()
scanner.PeriodicScan(config.ProtectedDirs, db, log, mailPath, scanInterval) scanner.PeriodicScan(config.ProtectedDirs, db, logger, mailPath, scanInterval)
}() }()
} }
if len(dirs) > 0 { if len(dirs) > 0 {
go new_file_monitor.Monitor_new_files(dirs, db, log, clamscanPath) go new_file_monitor.Monitor_new_files(dirs, db, logger, clamscanPath)
} }
if err := monitor_running_bins.MonitorExecutions(db, log, mailPath); err != nil { if err := monitor_running_bins.MonitorExecutions(db, logger, mailPath); err != nil {
log.Fatalf("Execution monitoring failed: %v", err) logger.Fatalf("Execution monitoring failed: %v", err)
os.Exit(4) // Exit with status code 4 os.Exit(4) // Exit with status code 4
} }
} }

@ -9,3 +9,5 @@ require (
) )
require github.com/fsnotify/fsnotify v1.9.0 require github.com/fsnotify/fsnotify v1.9.0
require gopkg.in/yaml.v3 v3.0.1

@ -6,3 +6,7 @@ github.com/yang3yen/xxtea-go v1.0.3 h1:C7yBcDRb909v39llhqx+QjAerOeWB+Oyqt/Z7yC7T
github.com/yang3yen/xxtea-go v1.0.3/go.mod h1:baa5JUNAgCuVCNqYuWSSNNGTmmDyNMTtSSlNMqfli9M= github.com/yang3yen/xxtea-go v1.0.3/go.mod h1:baa5JUNAgCuVCNqYuWSSNNGTmmDyNMTtSSlNMqfli9M=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -139,9 +139,9 @@ if [ ! -x /usr/bin/nano ]; then
echo "Installing nano text editor..." echo "Installing nano text editor..."
auto-pkg-installer nano auto-pkg-installer nano
fi fi
if [ ! -f /etc/execguard/config.json ]; then if [ ! -f /etc/execguard/config.yaml ]; then
/usr/bin/mkdir -p /etc/execguard /usr/bin/mkdir -p /etc/execguard
${USE_SUPER} cp config.json.example /etc/execguard/config.json ${USE_SUPER} cp config.yaml.example /etc/execguard/yaml.json
# Make an xxTea safe KEY! # Make an xxTea safe KEY!
passphrase_content=$(./execguard --newKey) passphrase_content=$(./execguard --newKey)
# Escape special characters (like &, \, and newlines) for sed # Escape special characters (like &, \, and newlines) for sed
@ -149,13 +149,13 @@ if [ ! -f /etc/execguard/config.json ]; then
# Replace using | as delimiter (avoiding / conflicts) # Replace using | as delimiter (avoiding / conflicts)
# Replace the passphrase line in the config file # Replace the passphrase line in the config file
${USE_SUPER} /usr/bin/sed -i "s|\"passphrase\": \"cdzTE1Gk6/VuDlnU\"|\"passphrase\": \"$escaped_content\"|g" /etc/execguard/config.json ${USE_SUPER} /usr/bin/sed -i "s|passphrase: \"cdzTE1Gk6/VuDlnU\"|passphrase: \"$escaped_content\"|g" /etc/execguard/config.yaml
# Prompt the user # Prompt the user
/usr/bin/echo "Please modidy your config home user's folders!!" /usr/bin/echo "Please modify your config home user's folders!!"
read -p "Do you want to edit your config.json file with nano? [y/N] " choice read -p "Do you want to edit your config.yaml file with nano? [y/N] " choice
case "$choice" in case "$choice" in
y|Y|[yY][eE][sS]) y|Y|[yY][eE][sS])
${USE_SUPER} /usr/bin/nano /etc/execguard/config.json ${USE_SUPER} /usr/bin/nano /etc/execguard/config.yaml
echo "File has been edited." echo "File has been edited."
;; ;;
*) *)
@ -163,7 +163,7 @@ if [ ! -f /etc/execguard/config.json ]; then
;; ;;
esac esac
fi fi
${USE_SUPER} /usr/bin/chmod 640 /etc/execguard/config.json ${USE_SUPER} /usr/bin/chmod 640 /etc/execguard/config.yaml
if [ ! -f /etc/systemd/system/execguard@.service ]; then if [ ! -f /etc/systemd/system/execguard@.service ]; then
/usr/bin/echo "Adding SystemD Serivce file..." /usr/bin/echo "Adding SystemD Serivce file..."

Loading…
Cancel
Save