Tighten windows sqlite database permissions (#1769)
This commit is contained in:
parent
52447f6999
commit
bfbe180101
6 changed files with 109 additions and 6 deletions
1
.github/workflows/go-tests-windows.yml
vendored
1
.github/workflows/go-tests-windows.yml
vendored
|
@ -41,6 +41,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
go install github.com/kyoh86/richgo@v0.3.10
|
go install github.com/kyoh86/richgo@v0.3.10
|
||||||
go test -coverprofile coverage.out -covermode=atomic ./... > out.txt
|
go test -coverprofile coverage.out -covermode=atomic ./... > out.txt
|
||||||
|
if(!$?) { cat out.txt | sed 's/ *coverage:.*of statements in.*//' | richgo testfilter; Exit 1 }
|
||||||
cat out.txt | sed 's/ *coverage:.*of statements in.*//' | richgo testfilter
|
cat out.txt | sed 's/ *coverage:.*of statements in.*//' | richgo testfilter
|
||||||
|
|
||||||
- name: Upload unit coverage to Codecov
|
- name: Upload unit coverage to Codecov
|
||||||
|
|
|
@ -460,7 +460,12 @@ exclude_regexps: ["\\.gz$"]`
|
||||||
if err != nil {
|
if err != nil {
|
||||||
subLogger.Fatalf("unexpected error: %s", err)
|
subLogger.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
expectedLogOutput := "Skipping file test_files/test.log.gz as it matches exclude pattern"
|
var expectedLogOutput string
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
expectedLogOutput = "Skipping file test_files\\test.log.gz as it matches exclude pattern \\.gz"
|
||||||
|
} else {
|
||||||
|
expectedLogOutput = "Skipping file test_files/test.log.gz as it matches exclude pattern"
|
||||||
|
}
|
||||||
if hook.LastEntry() == nil {
|
if hook.LastEntry() == nil {
|
||||||
t.Fatalf("expected output %s, but got nothing", expectedLogOutput)
|
t.Fatalf("expected output %s, but got nothing", expectedLogOutput)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package kafkaacquisition
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -114,6 +115,9 @@ func createTopic(topic string, broker string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamingAcquisition(t *testing.T) {
|
func TestStreamingAcquisition(t *testing.T) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
t.Skip("Skipping test on windows")
|
||||||
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
logs []string
|
logs []string
|
||||||
|
@ -181,6 +185,9 @@ topic: crowdsecplaintext`), subLogger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamingAcquisitionWithSSL(t *testing.T) {
|
func TestStreamingAcquisitionWithSSL(t *testing.T) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
t.Skip("Skipping test on windows")
|
||||||
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
logs []string
|
logs []string
|
||||||
|
|
|
@ -61,7 +61,6 @@ func NewClient(config *csconfig.DatabaseCfg) (*Client, error) {
|
||||||
entOpt := ent.Log(entLogger.Debug)
|
entOpt := ent.Log(entLogger.Debug)
|
||||||
switch config.Type {
|
switch config.Type {
|
||||||
case "sqlite":
|
case "sqlite":
|
||||||
|
|
||||||
/*if it's the first startup, we want to touch and chmod file*/
|
/*if it's the first startup, we want to touch and chmod file*/
|
||||||
if _, err := os.Stat(config.DbPath); os.IsNotExist(err) {
|
if _, err := os.Stat(config.DbPath); os.IsNotExist(err) {
|
||||||
f, err := os.OpenFile(config.DbPath, os.O_CREATE|os.O_RDWR, 0600)
|
f, err := os.OpenFile(config.DbPath, os.O_CREATE|os.O_RDWR, 0600)
|
||||||
|
@ -71,10 +70,10 @@ func NewClient(config *csconfig.DatabaseCfg) (*Client, error) {
|
||||||
if err := f.Close(); err != nil {
|
if err := f.Close(); err != nil {
|
||||||
return &Client{}, errors.Wrapf(err, "failed to create SQLite database file %q", config.DbPath)
|
return &Client{}, errors.Wrapf(err, "failed to create SQLite database file %q", config.DbPath)
|
||||||
}
|
}
|
||||||
} else { /*ensure file perms*/
|
}
|
||||||
if err := os.Chmod(config.DbPath, 0660); err != nil {
|
//Always try to set permissions to simplify a bit the code for windows (as the permissions set by OpenFile will be garbage)
|
||||||
return &Client{}, fmt.Errorf("unable to set perms on %s: %v", config.DbPath, err)
|
if err := setFilePerm(config.DbPath, 0600); err != nil {
|
||||||
}
|
return &Client{}, fmt.Errorf("unable to set perms on %s: %v", config.DbPath, err)
|
||||||
}
|
}
|
||||||
if config.UseWal == nil {
|
if config.UseWal == nil {
|
||||||
entLogger.Warn("you are using sqlite without WAL, this can have an impact of performance. If you do not store the database in a network share, set db_config.use_wal to true. Set explicitly to false to disable this warning.")
|
entLogger.Warn("you are using sqlite without WAL, this can have an impact of performance. If you do not store the database in a network share, set db_config.use_wal to true. Set explicitly to false to disable this warning.")
|
||||||
|
|
12
pkg/database/file_utils.go
Normal file
12
pkg/database/file_utils.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setFilePerm(path string, mode fs.FileMode) error {
|
||||||
|
return os.Chmod(path, mode)
|
||||||
|
}
|
79
pkg/database/file_utils_windows.go
Normal file
79
pkg/database/file_utils_windows.go
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setFilePerm(path string, mode fs.FileMode) error {
|
||||||
|
//On windows, we don't care about the mode, just make sure the file is only readable/writable by the owner and group
|
||||||
|
|
||||||
|
sd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("while getting security info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
currentOwner, defaulted, err := sd.Owner()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("while getting owner: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("current owner is %s (%v) (defaulted: %v)", currentOwner.String(), currentOwner, defaulted)
|
||||||
|
|
||||||
|
currentGroup, defaulted, err := sd.Group()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("while getting group: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentGroup == nil {
|
||||||
|
log.Debugf("current group is nil (defaulted: %v), using builtin admin instead", defaulted)
|
||||||
|
currentGroup, err = windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("while creating admin SID: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("current group is %s (%v) (defaulted: %v)", currentGroup.String(), currentGroup, defaulted)
|
||||||
|
|
||||||
|
dacl, err := windows.ACLFromEntries(
|
||||||
|
[]windows.EXPLICIT_ACCESS{
|
||||||
|
{
|
||||||
|
AccessPermissions: windows.GENERIC_ALL,
|
||||||
|
AccessMode: windows.GRANT_ACCESS,
|
||||||
|
Inheritance: windows.NO_INHERITANCE,
|
||||||
|
Trustee: windows.TRUSTEE{
|
||||||
|
MultipleTrusteeOperation: windows.NO_MULTIPLE_TRUSTEE,
|
||||||
|
TrusteeForm: windows.TRUSTEE_IS_SID,
|
||||||
|
TrusteeType: windows.TRUSTEE_IS_USER,
|
||||||
|
TrusteeValue: windows.TrusteeValueFromSID(currentOwner),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AccessPermissions: windows.GENERIC_ALL,
|
||||||
|
AccessMode: windows.GRANT_ACCESS,
|
||||||
|
Inheritance: windows.NO_INHERITANCE,
|
||||||
|
Trustee: windows.TRUSTEE{
|
||||||
|
MultipleTrusteeOperation: windows.NO_MULTIPLE_TRUSTEE,
|
||||||
|
TrusteeForm: windows.TRUSTEE_IS_SID,
|
||||||
|
TrusteeType: windows.TRUSTEE_IS_GROUP,
|
||||||
|
TrusteeValue: windows.TrusteeValueFromSID(currentGroup),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("while creating ACL: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = windows.SetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION, nil, nil, dacl, nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("while setting security info: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in a new issue