Skip to content

Commit

Permalink
Merge pull request #1787 from safing/develop
Browse files Browse the repository at this point in the history
v1.6.29
  • Loading branch information
stenya authored Jan 13, 2025
2 parents 6e173e3 + 3478622 commit f021ec2
Show file tree
Hide file tree
Showing 46 changed files with 838 additions and 183 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ go.mod.*
vendor

# testing
testing
spn/testing/simple/testdata
testdata

# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.a
Expand Down
5 changes: 5 additions & 0 deletions Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ build:
# ./dist/all/assets.zip
BUILD +assets

build-spn:
BUILD +go-build --CMDS="hub" --GOOS="linux" --GOARCH="amd64"
BUILD +go-build --CMDS="hub" --GOOS="linux" --GOARCH="arm64"
# TODO: Add other platforms

go-ci:
BUILD +go-build --GOOS="linux" --GOARCH="amd64"
BUILD +go-build --GOOS="linux" --GOARCH="arm64"
Expand Down
4 changes: 2 additions & 2 deletions base/config/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ func InitializeUnitTestDataroot(testName string) (string, error) {
return "", fmt.Errorf("failed to make tmp dir: %w", err)
}

ds := utils.NewDirStructure(basePath, 0o0755)
ds := utils.NewDirStructure(basePath, utils.PublicReadPermission)
SetDataRoot(ds)
err = dataroot.Initialize(basePath, 0o0755)
err = dataroot.Initialize(basePath, utils.PublicReadPermission)
if err != nil {
return "", fmt.Errorf("failed to initialize dataroot: %w", err)
}
Expand Down
6 changes: 3 additions & 3 deletions base/database/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var (

// InitializeWithPath initializes the database at the specified location using a path.
func InitializeWithPath(dirPath string) error {
return Initialize(utils.NewDirStructure(dirPath, 0o0755))
return Initialize(utils.NewDirStructure(dirPath, utils.PublicReadPermission))
}

// Initialize initializes the database at the specified location using a dir structure.
Expand All @@ -34,7 +34,7 @@ func Initialize(dirStructureRoot *utils.DirStructure) error {
rootStructure = dirStructureRoot

// ensure root and databases dirs
databasesStructure = rootStructure.ChildDir(databasesSubDir, 0o0700)
databasesStructure = rootStructure.ChildDir(databasesSubDir, utils.AdminOnlyPermission)
err := databasesStructure.Ensure()
if err != nil {
return fmt.Errorf("could not create/open database directory (%s): %w", rootStructure.Path, err)
Expand Down Expand Up @@ -67,7 +67,7 @@ func Shutdown() (err error) {

// getLocation returns the storage location for the given name and type.
func getLocation(name, storageType string) (string, error) {
location := databasesStructure.ChildDir(name, 0o0700).ChildDir(storageType, 0o0700)
location := databasesStructure.ChildDir(name, utils.AdminOnlyPermission).ChildDir(storageType, utils.AdminOnlyPermission)
// check location
err := location.Ensure()
if err != nil {
Expand Down
8 changes: 2 additions & 6 deletions base/database/storage/fstree/fstree.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"strings"
"time"

"github.com/hectane/go-acl"
"github.com/safing/portmaster/base/database/iterator"
"github.com/safing/portmaster/base/database/query"
"github.com/safing/portmaster/base/database/record"
Expand Down Expand Up @@ -289,11 +288,8 @@ func writeFile(filename string, data []byte, perm os.FileMode) error {
defer t.Cleanup() //nolint:errcheck

// Set permissions before writing data, in case the data is sensitive.
if onWindows {
err = acl.Chmod(filename, perm)
} else {
err = t.Chmod(perm)
}
// TODO(vladimir): to set permissions on windows we need the full path of the file.
err = t.Chmod(perm)
if err != nil {
return err
}
Expand Down
3 changes: 1 addition & 2 deletions base/dataroot/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package dataroot

import (
"errors"
"os"

"github.com/safing/portmaster/base/utils"
)

var root *utils.DirStructure

// Initialize initializes the data root directory.
func Initialize(rootDir string, perm os.FileMode) error {
func Initialize(rootDir string, perm utils.FSPermission) error {
if root != nil {
return errors.New("already initialized")
}
Expand Down
1 change: 1 addition & 0 deletions base/info/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func Set(setName string, setVersion string, setLicenseName string) {

if setVersion != "" {
version = setVersion
versionNumber = setVersion
}
}

Expand Down
17 changes: 5 additions & 12 deletions base/updater/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import (
"path/filepath"
"time"

"github.com/hectane/go-acl"
"github.com/safing/jess/filesig"
"github.com/safing/jess/lhash"
"github.com/safing/portmaster/base/log"
"github.com/safing/portmaster/base/utils"
"github.com/safing/portmaster/base/utils/renameio"
)

Expand Down Expand Up @@ -137,17 +137,10 @@ func (reg *ResourceRegistry) fetchFile(ctx context.Context, client *http.Client,
return fmt.Errorf("%s: failed to finalize file %s: %w", reg.Name, rv.storagePath(), err)
}
// set permissions
if onWindows {
err = acl.Chmod(rv.storagePath(), 0o0755)
if err != nil {
log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err)
}
} else {
// TODO: only set executable files to 0755, set other to 0644
err = os.Chmod(rv.storagePath(), 0o0755) //nolint:gosec // See TODO above.
if err != nil {
log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err)
}
// TODO: distinguish between executable and non executable files.
err = utils.SetExecPermission(rv.storagePath(), utils.PublicReadPermission)
if err != nil {
log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err)
}

log.Debugf("%s: fetched %s and stored to %s", reg.Name, downloadURL, rv.storagePath())
Expand Down
7 changes: 1 addition & 6 deletions base/updater/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"sync"

"github.com/safing/portmaster/base/log"
"github.com/safing/portmaster/base/utils"
)

const (
onWindows = runtime.GOOS == "windows"
)

// ResourceRegistry is a registry for managing update resources.
type ResourceRegistry struct {
sync.RWMutex
Expand Down Expand Up @@ -98,7 +93,7 @@ func (reg *ResourceRegistry) Initialize(storageDir *utils.DirStructure) error {

// initialize private attributes
reg.storageDir = storageDir
reg.tmpDir = storageDir.ChildDir("tmp", 0o0700)
reg.tmpDir = storageDir.ChildDir("tmp", utils.AdminOnlyPermission)
reg.resources = make(map[string]*Resource)
if reg.state == nil {
reg.state = &RegistryState{}
Expand Down
2 changes: 1 addition & 1 deletion base/updater/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestMain(m *testing.M) {
DevMode: true,
Online: true,
}
err = registry.Initialize(utils.NewDirStructure(tmpDir, 0o0777))
err = registry.Initialize(utils.NewDirStructure(tmpDir, utils.PublicWritePermission))
if err != nil {
panic(err)
}
Expand Down
24 changes: 11 additions & 13 deletions base/utils/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import (
"io/fs"
"os"
"runtime"

"github.com/hectane/go-acl"
)

const isWindows = runtime.GOOS == "windows"

// EnsureDirectory ensures that the given directory exists and that is has the given permissions set.
// If path is a file, it is deleted and a directory created.
func EnsureDirectory(path string, perm os.FileMode) error {
func EnsureDirectory(path string, perm FSPermission) error {
// open path
f, err := os.Stat(path)
if err == nil {
Expand All @@ -23,10 +21,10 @@ func EnsureDirectory(path string, perm os.FileMode) error {
// directory exists, check permissions
if isWindows {
// Ignore windows permission error. For none admin users it will always fail.
acl.Chmod(path, perm)
_ = SetDirPermission(path, perm)
return nil
} else if f.Mode().Perm() != perm {
return os.Chmod(path, perm)
} else if f.Mode().Perm() != perm.AsUnixDirExecPermission() {
return SetDirPermission(path, perm)
}
return nil
}
Expand All @@ -37,17 +35,17 @@ func EnsureDirectory(path string, perm os.FileMode) error {
}
// file does not exist (or has been deleted)
if err == nil || errors.Is(err, fs.ErrNotExist) {
err = os.Mkdir(path, perm)
err = os.Mkdir(path, perm.AsUnixDirExecPermission())
if err != nil {
return fmt.Errorf("could not create dir %s: %w", path, err)
}
if isWindows {
// Ignore windows permission error. For none admin users it will always fail.
acl.Chmod(path, perm)
return nil
} else {
return os.Chmod(path, perm)
// Set permissions.
err = SetDirPermission(path, perm)
// Ignore windows permission error. For none admin users it will always fail.
if !isWindows {
return err
}
return nil
}
// other error opening path
return fmt.Errorf("failed to access %s: %w", path, err)
Expand Down
20 changes: 20 additions & 0 deletions base/utils/permissions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build !windows

package utils

import "os"

// SetDirPermission sets the permission of a directory.
func SetDirPermission(path string, perm FSPermission) error {
return os.Chmod(path, perm.AsUnixDirExecPermission())
}

// SetExecPermission sets the permission of an executable file.
func SetExecPermission(path string, perm FSPermission) error {
return SetDirPermission(path, perm)
}

// SetFilePermission sets the permission of a non executable file.
func SetFilePermission(path string, perm FSPermission) error {
return os.Chmod(path, perm.AsUnixFilePermission())
}
79 changes: 79 additions & 0 deletions base/utils/permissions_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//go:build windows

package utils

import (
"github.com/hectane/go-acl"
"golang.org/x/sys/windows"
)

var (
systemSID *windows.SID
adminsSID *windows.SID
usersSID *windows.SID
)

func init() {
// Initialize Security ID for all need groups.
// Reference: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers
var err error
systemSID, err = windows.StringToSid("S-1-5-18") // SYSTEM (Local System)
if err != nil {
panic(err)
}
adminsSID, err = windows.StringToSid("S-1-5-32-544") // Administrators
if err != nil {
panic(err)
}
usersSID, err = windows.StringToSid("S-1-5-32-545") // Users
if err != nil {
panic(err)
}
}

// SetDirPermission sets the permission of a directory.
func SetDirPermission(path string, perm FSPermission) error {
SetFilePermission(path, perm)
return nil
}

// SetExecPermission sets the permission of an executable file.
func SetExecPermission(path string, perm FSPermission) error {
SetFilePermission(path, perm)
return nil
}

// SetFilePermission sets the permission of a non executable file.
func SetFilePermission(path string, perm FSPermission) {
switch perm {
case AdminOnlyPermission:
// Set only admin rights, remove all others.
acl.Apply(
path,
true,
false,
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID),
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID),
)
case PublicReadPermission:
// Set admin rights and read/execute rights for users, remove all others.
acl.Apply(
path,
true,
false,
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID),
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID),
acl.GrantSid(windows.GENERIC_READ|windows.GENERIC_EXECUTE, usersSID),
)
case PublicWritePermission:
// Set full control to admin and regular users. Guest users will not have access.
acl.Apply(
path,
true,
false,
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, systemSID),
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, adminsSID),
acl.GrantSid(windows.GENERIC_ALL|windows.STANDARD_RIGHTS_ALL, usersSID),
)
}
}
Loading

0 comments on commit f021ec2

Please sign in to comment.