mirror of
https://github.com/safing/portmaster
synced 2025-04-07 20:49:10 +00:00
Merge pull request #1766 from safing/fix/windows-permission2
Fix windows permissions
This commit is contained in:
commit
3ee214abaf
23 changed files with 204 additions and 83 deletions
base
config
database
dataroot
updater
utils
cmds
service
|
@ -144,9 +144,9 @@ func InitializeUnitTestDataroot(testName string) (string, error) {
|
||||||
return "", fmt.Errorf("failed to make tmp dir: %w", err)
|
return "", fmt.Errorf("failed to make tmp dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds := utils.NewDirStructure(basePath, 0o0755)
|
ds := utils.NewDirStructure(basePath, utils.PublicReadPermission)
|
||||||
SetDataRoot(ds)
|
SetDataRoot(ds)
|
||||||
err = dataroot.Initialize(basePath, 0o0755)
|
err = dataroot.Initialize(basePath, utils.PublicReadPermission)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to initialize dataroot: %w", err)
|
return "", fmt.Errorf("failed to initialize dataroot: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ var (
|
||||||
|
|
||||||
// InitializeWithPath initializes the database at the specified location using a path.
|
// InitializeWithPath initializes the database at the specified location using a path.
|
||||||
func InitializeWithPath(dirPath string) error {
|
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.
|
// Initialize initializes the database at the specified location using a dir structure.
|
||||||
|
@ -34,7 +34,7 @@ func Initialize(dirStructureRoot *utils.DirStructure) error {
|
||||||
rootStructure = dirStructureRoot
|
rootStructure = dirStructureRoot
|
||||||
|
|
||||||
// ensure root and databases dirs
|
// ensure root and databases dirs
|
||||||
databasesStructure = rootStructure.ChildDir(databasesSubDir, 0o0700)
|
databasesStructure = rootStructure.ChildDir(databasesSubDir, utils.AdminOnlyPermission)
|
||||||
err := databasesStructure.Ensure()
|
err := databasesStructure.Ensure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not create/open database directory (%s): %w", rootStructure.Path, err)
|
return fmt.Errorf("could not create/open database directory (%s): %w", rootStructure.Path, err)
|
||||||
|
@ -67,7 +67,7 @@ func Shutdown() (err error) {
|
||||||
|
|
||||||
// getLocation returns the storage location for the given name and type.
|
// getLocation returns the storage location for the given name and type.
|
||||||
func getLocation(name, storageType string) (string, error) {
|
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
|
// check location
|
||||||
err := location.Ensure()
|
err := location.Ensure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hectane/go-acl"
|
|
||||||
"github.com/safing/portmaster/base/database/iterator"
|
"github.com/safing/portmaster/base/database/iterator"
|
||||||
"github.com/safing/portmaster/base/database/query"
|
"github.com/safing/portmaster/base/database/query"
|
||||||
"github.com/safing/portmaster/base/database/record"
|
"github.com/safing/portmaster/base/database/record"
|
||||||
|
@ -289,11 +288,8 @@ func writeFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
defer t.Cleanup() //nolint:errcheck
|
defer t.Cleanup() //nolint:errcheck
|
||||||
|
|
||||||
// Set permissions before writing data, in case the data is sensitive.
|
// Set permissions before writing data, in case the data is sensitive.
|
||||||
if onWindows {
|
// TODO(vladimir): to set permissions on windows we need the full path of the file.
|
||||||
err = acl.Chmod(filename, perm)
|
err = t.Chmod(perm)
|
||||||
} else {
|
|
||||||
err = t.Chmod(perm)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package dataroot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/safing/portmaster/base/utils"
|
"github.com/safing/portmaster/base/utils"
|
||||||
)
|
)
|
||||||
|
@ -10,7 +9,7 @@ import (
|
||||||
var root *utils.DirStructure
|
var root *utils.DirStructure
|
||||||
|
|
||||||
// Initialize initializes the data root directory.
|
// 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 {
|
if root != nil {
|
||||||
return errors.New("already initialized")
|
return errors.New("already initialized")
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hectane/go-acl"
|
|
||||||
"github.com/safing/jess/filesig"
|
"github.com/safing/jess/filesig"
|
||||||
"github.com/safing/jess/lhash"
|
"github.com/safing/jess/lhash"
|
||||||
"github.com/safing/portmaster/base/log"
|
"github.com/safing/portmaster/base/log"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
"github.com/safing/portmaster/base/utils/renameio"
|
"github.com/safing/portmaster/base/utils/renameio"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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)
|
return fmt.Errorf("%s: failed to finalize file %s: %w", reg.Name, rv.storagePath(), err)
|
||||||
}
|
}
|
||||||
// set permissions
|
// set permissions
|
||||||
if onWindows {
|
// TODO: distinguish between executable and non executable files.
|
||||||
err = acl.Chmod(rv.storagePath(), 0o0755)
|
err = utils.SetExecPermission(rv.storagePath(), utils.PublicReadPermission)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("%s: failed to set permissions on downloaded file %s: %s", reg.Name, rv.storagePath(), err)
|
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("%s: fetched %s and stored to %s", reg.Name, downloadURL, rv.storagePath())
|
log.Debugf("%s: fetched %s and stored to %s", reg.Name, downloadURL, rv.storagePath())
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -13,10 +12,6 @@ import (
|
||||||
"github.com/safing/portmaster/base/utils"
|
"github.com/safing/portmaster/base/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
onWindows = runtime.GOOS == "windows"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ResourceRegistry is a registry for managing update resources.
|
// ResourceRegistry is a registry for managing update resources.
|
||||||
type ResourceRegistry struct {
|
type ResourceRegistry struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
|
@ -98,7 +93,7 @@ func (reg *ResourceRegistry) Initialize(storageDir *utils.DirStructure) error {
|
||||||
|
|
||||||
// initialize private attributes
|
// initialize private attributes
|
||||||
reg.storageDir = storageDir
|
reg.storageDir = storageDir
|
||||||
reg.tmpDir = storageDir.ChildDir("tmp", 0o0700)
|
reg.tmpDir = storageDir.ChildDir("tmp", utils.AdminOnlyPermission)
|
||||||
reg.resources = make(map[string]*Resource)
|
reg.resources = make(map[string]*Resource)
|
||||||
if reg.state == nil {
|
if reg.state == nil {
|
||||||
reg.state = &RegistryState{}
|
reg.state = &RegistryState{}
|
||||||
|
|
|
@ -20,7 +20,7 @@ func TestMain(m *testing.M) {
|
||||||
DevMode: true,
|
DevMode: true,
|
||||||
Online: true,
|
Online: true,
|
||||||
}
|
}
|
||||||
err = registry.Initialize(utils.NewDirStructure(tmpDir, 0o0777))
|
err = registry.Initialize(utils.NewDirStructure(tmpDir, utils.PublicWritePermission))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,13 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/hectane/go-acl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const isWindows = runtime.GOOS == "windows"
|
const isWindows = runtime.GOOS == "windows"
|
||||||
|
|
||||||
// EnsureDirectory ensures that the given directory exists and that is has the given permissions set.
|
// 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.
|
// 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
|
// open path
|
||||||
f, err := os.Stat(path)
|
f, err := os.Stat(path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -23,10 +21,10 @@ func EnsureDirectory(path string, perm os.FileMode) error {
|
||||||
// directory exists, check permissions
|
// directory exists, check permissions
|
||||||
if isWindows {
|
if isWindows {
|
||||||
// Ignore windows permission error. For none admin users it will always fail.
|
// Ignore windows permission error. For none admin users it will always fail.
|
||||||
acl.Chmod(path, perm)
|
_ = SetDirPermission(path, perm)
|
||||||
return nil
|
return nil
|
||||||
} else if f.Mode().Perm() != perm {
|
} else if f.Mode().Perm() != perm.AsUnixDirExecPermission() {
|
||||||
return os.Chmod(path, perm)
|
return SetDirPermission(path, perm)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -37,17 +35,17 @@ func EnsureDirectory(path string, perm os.FileMode) error {
|
||||||
}
|
}
|
||||||
// file does not exist (or has been deleted)
|
// file does not exist (or has been deleted)
|
||||||
if err == nil || errors.Is(err, fs.ErrNotExist) {
|
if err == nil || errors.Is(err, fs.ErrNotExist) {
|
||||||
err = os.Mkdir(path, perm)
|
err = os.Mkdir(path, perm.AsUnixDirExecPermission())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not create dir %s: %w", path, err)
|
return fmt.Errorf("could not create dir %s: %w", path, err)
|
||||||
}
|
}
|
||||||
if isWindows {
|
// Set permissions.
|
||||||
// Ignore windows permission error. For none admin users it will always fail.
|
err = SetDirPermission(path, perm)
|
||||||
acl.Chmod(path, perm)
|
// Ignore windows permission error. For none admin users it will always fail.
|
||||||
return nil
|
if !isWindows {
|
||||||
} else {
|
return err
|
||||||
return os.Chmod(path, perm)
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
// other error opening path
|
// other error opening path
|
||||||
return fmt.Errorf("failed to access %s: %w", path, err)
|
return fmt.Errorf("failed to access %s: %w", path, err)
|
||||||
|
|
20
base/utils/permissions.go
Normal file
20
base/utils/permissions.go
Normal file
|
@ -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
base/utils/permissions_windows.go
Normal file
79
base/utils/permissions_windows.go
Normal file
|
@ -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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,25 +2,61 @@ package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"io/fs"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FSPermission uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
AdminOnlyPermission FSPermission = iota
|
||||||
|
PublicReadPermission
|
||||||
|
PublicWritePermission
|
||||||
|
)
|
||||||
|
|
||||||
|
// AsUnixDirExecPermission return the corresponding unix permission for a directory or executable.
|
||||||
|
func (perm FSPermission) AsUnixDirExecPermission() fs.FileMode {
|
||||||
|
switch perm {
|
||||||
|
case AdminOnlyPermission:
|
||||||
|
return 0o700
|
||||||
|
case PublicReadPermission:
|
||||||
|
return 0o755
|
||||||
|
case PublicWritePermission:
|
||||||
|
return 0o777
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsUnixFilePermission return the corresponding unix permission for a regular file.
|
||||||
|
func (perm FSPermission) AsUnixFilePermission() fs.FileMode {
|
||||||
|
switch perm {
|
||||||
|
case AdminOnlyPermission:
|
||||||
|
return 0o600
|
||||||
|
case PublicReadPermission:
|
||||||
|
return 0o644
|
||||||
|
case PublicWritePermission:
|
||||||
|
return 0o666
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// DirStructure represents a directory structure with permissions that should be enforced.
|
// DirStructure represents a directory structure with permissions that should be enforced.
|
||||||
type DirStructure struct {
|
type DirStructure struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
|
||||||
Path string
|
Path string
|
||||||
Dir string
|
Dir string
|
||||||
Perm os.FileMode
|
Perm FSPermission
|
||||||
Parent *DirStructure
|
Parent *DirStructure
|
||||||
Children map[string]*DirStructure
|
Children map[string]*DirStructure
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDirStructure returns a new DirStructure.
|
// NewDirStructure returns a new DirStructure.
|
||||||
func NewDirStructure(path string, perm os.FileMode) *DirStructure {
|
func NewDirStructure(path string, perm FSPermission) *DirStructure {
|
||||||
return &DirStructure{
|
return &DirStructure{
|
||||||
Path: path,
|
Path: path,
|
||||||
Perm: perm,
|
Perm: perm,
|
||||||
|
@ -29,7 +65,7 @@ func NewDirStructure(path string, perm os.FileMode) *DirStructure {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChildDir adds a new child DirStructure and returns it. Should the child already exist, the existing child is returned and the permissions are updated.
|
// ChildDir adds a new child DirStructure and returns it. Should the child already exist, the existing child is returned and the permissions are updated.
|
||||||
func (ds *DirStructure) ChildDir(dirName string, perm os.FileMode) (child *DirStructure) {
|
func (ds *DirStructure) ChildDir(dirName string, perm FSPermission) (child *DirStructure) {
|
||||||
ds.Lock()
|
ds.Lock()
|
||||||
defer ds.Unlock()
|
defer ds.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,13 @@ func ExampleDirStructure() {
|
||||||
// output:
|
// output:
|
||||||
// / [755]
|
// / [755]
|
||||||
// /repo [777]
|
// /repo [777]
|
||||||
// /repo/b [707]
|
// /repo/b [755]
|
||||||
// /repo/b/c [750]
|
// /repo/b/c [777]
|
||||||
// /repo/b/d [707]
|
// /repo/b/d [755]
|
||||||
// /repo/b/d/e [707]
|
// /repo/b/d/e [755]
|
||||||
// /repo/b/d/f [707]
|
// /repo/b/d/f [755]
|
||||||
// /repo/b/d/f/g [707]
|
// /repo/b/d/f/g [755]
|
||||||
// /repo/b/d/f/g/h [707]
|
// /repo/b/d/f/g/h [755]
|
||||||
// /secret [700]
|
// /secret [700]
|
||||||
|
|
||||||
basePath, err := os.MkdirTemp("", "")
|
basePath, err := os.MkdirTemp("", "")
|
||||||
|
@ -28,12 +28,12 @@ func ExampleDirStructure() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ds := NewDirStructure(basePath, 0o0755)
|
ds := NewDirStructure(basePath, PublicReadPermission)
|
||||||
secret := ds.ChildDir("secret", 0o0700)
|
secret := ds.ChildDir("secret", AdminOnlyPermission)
|
||||||
repo := ds.ChildDir("repo", 0o0777)
|
repo := ds.ChildDir("repo", PublicWritePermission)
|
||||||
_ = repo.ChildDir("a", 0o0700)
|
_ = repo.ChildDir("a", AdminOnlyPermission)
|
||||||
b := repo.ChildDir("b", 0o0707)
|
b := repo.ChildDir("b", PublicReadPermission)
|
||||||
c := b.ChildDir("c", 0o0750)
|
c := b.ChildDir("c", PublicWritePermission)
|
||||||
|
|
||||||
err = ds.Ensure()
|
err = ds.Ensure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -225,14 +225,14 @@ func configureRegistry(mustLoadIndex bool) error {
|
||||||
// Remove left over quotes.
|
// Remove left over quotes.
|
||||||
dataDir = strings.Trim(dataDir, `\"`)
|
dataDir = strings.Trim(dataDir, `\"`)
|
||||||
// Initialize data root.
|
// Initialize data root.
|
||||||
err := dataroot.Initialize(dataDir, 0o0755)
|
err := dataroot.Initialize(dataDir, utils.PublicReadPermission)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to initialize data root: %w", err)
|
return fmt.Errorf("failed to initialize data root: %w", err)
|
||||||
}
|
}
|
||||||
dataRoot = dataroot.Root()
|
dataRoot = dataroot.Root()
|
||||||
|
|
||||||
// Initialize registry.
|
// Initialize registry.
|
||||||
err = registry.Initialize(dataRoot.ChildDir("updates", 0o0755))
|
err = registry.Initialize(dataRoot.ChildDir("updates", utils.PublicReadPermission))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ var cleanStructureCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanAndEnsureExecDir() error {
|
func cleanAndEnsureExecDir() error {
|
||||||
execDir := dataRoot.ChildDir("exec", 0o777)
|
execDir := dataRoot.ChildDir("exec", utils.PublicWritePermission)
|
||||||
|
|
||||||
// Clean up and remove exec dir.
|
// Clean up and remove exec dir.
|
||||||
err := os.RemoveAll(execDir.Path)
|
err := os.RemoveAll(execDir.Path)
|
||||||
|
|
|
@ -179,14 +179,14 @@ func configureRegistry(mustLoadIndex bool) error {
|
||||||
// Remove left over quotes.
|
// Remove left over quotes.
|
||||||
dataDir = strings.Trim(dataDir, `\"`)
|
dataDir = strings.Trim(dataDir, `\"`)
|
||||||
// Initialize data root.
|
// Initialize data root.
|
||||||
err := dataroot.Initialize(dataDir, 0o0755)
|
err := dataroot.Initialize(dataDir, utils.PublicReadPermission)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to initialize data root: %w", err)
|
return fmt.Errorf("failed to initialize data root: %w", err)
|
||||||
}
|
}
|
||||||
dataRoot = dataroot.Root()
|
dataRoot = dataroot.Root()
|
||||||
|
|
||||||
// Initialize registry.
|
// Initialize registry.
|
||||||
err = registry.Initialize(dataRoot.ChildDir("updates", 0o0755))
|
err = registry.Initialize(dataRoot.ChildDir("updates", utils.PublicReadPermission))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ func configureRegistry(mustLoadIndex bool) error {
|
||||||
|
|
||||||
func ensureLoggingDir() error {
|
func ensureLoggingDir() error {
|
||||||
// set up logs root
|
// set up logs root
|
||||||
logsRoot = dataRoot.ChildDir("logs", 0o0777)
|
logsRoot = dataRoot.ChildDir("logs", utils.PublicWritePermission)
|
||||||
err := logsRoot.Ensure()
|
err := logsRoot.Ensure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to initialize logs root (%q): %w", logsRoot.Path, err)
|
return fmt.Errorf("failed to initialize logs root (%q): %w", logsRoot.Path, err)
|
||||||
|
|
|
@ -31,7 +31,7 @@ var rootCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
registry = &updater.ResourceRegistry{}
|
registry = &updater.ResourceRegistry{}
|
||||||
err = registry.Initialize(utils.NewDirStructure(absDistPath, 0o0755))
|
err = registry.Initialize(utils.NewDirStructure(absDistPath, utils.PublicReadPermission))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/safing/portmaster/base/updater"
|
"github.com/safing/portmaster/base/updater"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -63,7 +64,7 @@ func release(cmd *cobra.Command, args []string) error {
|
||||||
fmt.Println("aborted...")
|
fmt.Println("aborted...")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
symlinksDir := registry.StorageDir().ChildDir("latest", 0o755)
|
symlinksDir := registry.StorageDir().ChildDir("latest", utils.PublicReadPermission)
|
||||||
err = registry.CreateSymlinks(symlinksDir)
|
err = registry.CreateSymlinks(symlinksDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/safing/portmaster/base/api"
|
"github.com/safing/portmaster/base/api"
|
||||||
"github.com/safing/portmaster/base/dataroot"
|
"github.com/safing/portmaster/base/dataroot"
|
||||||
"github.com/safing/portmaster/base/info"
|
"github.com/safing/portmaster/base/info"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
"github.com/safing/portmaster/service/mgr"
|
"github.com/safing/portmaster/service/mgr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ func prep(instance instance) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize structure
|
// initialize structure
|
||||||
err := dataroot.Initialize(dataDir, 0o0755)
|
err := dataroot.Initialize(dataDir, utils.PublicReadPermission)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/safing/portmaster/base/config"
|
"github.com/safing/portmaster/base/config"
|
||||||
"github.com/safing/portmaster/base/dataroot"
|
"github.com/safing/portmaster/base/dataroot"
|
||||||
"github.com/safing/portmaster/base/log"
|
"github.com/safing/portmaster/base/log"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
"github.com/safing/portmaster/service/netquery/orm"
|
"github.com/safing/portmaster/service/netquery/orm"
|
||||||
"github.com/safing/portmaster/service/network"
|
"github.com/safing/portmaster/service/network"
|
||||||
"github.com/safing/portmaster/service/network/netutils"
|
"github.com/safing/portmaster/service/network/netutils"
|
||||||
|
@ -127,7 +128,7 @@ type (
|
||||||
// Note that write connections are serialized by the Database object before being
|
// Note that write connections are serialized by the Database object before being
|
||||||
// handed over to SQLite.
|
// handed over to SQLite.
|
||||||
func New(dbPath string) (*Database, error) {
|
func New(dbPath string) (*Database, error) {
|
||||||
historyParentDir := dataroot.Root().ChildDir("databases", 0o700)
|
historyParentDir := dataroot.Root().ChildDir("databases", utils.AdminOnlyPermission)
|
||||||
if err := historyParentDir.Ensure(); err != nil {
|
if err := historyParentDir.Ensure(); err != nil {
|
||||||
return nil, fmt.Errorf("failed to ensure database directory exists: %w", err)
|
return nil, fmt.Errorf("failed to ensure database directory exists: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -225,7 +226,7 @@ func (db *Database) Close() error {
|
||||||
|
|
||||||
// VacuumHistory rewrites the history database in order to purge deleted records.
|
// VacuumHistory rewrites the history database in order to purge deleted records.
|
||||||
func VacuumHistory(ctx context.Context) (err error) {
|
func VacuumHistory(ctx context.Context) (err error) {
|
||||||
historyParentDir := dataroot.Root().ChildDir("databases", 0o700)
|
historyParentDir := dataroot.Root().ChildDir("databases", utils.AdminOnlyPermission)
|
||||||
if err := historyParentDir.Ensure(); err != nil {
|
if err := historyParentDir.Ensure(); err != nil {
|
||||||
return fmt.Errorf("failed to ensure database directory exists: %w", err)
|
return fmt.Errorf("failed to ensure database directory exists: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/safing/portmaster/base/database/migration"
|
"github.com/safing/portmaster/base/database/migration"
|
||||||
"github.com/safing/portmaster/base/dataroot"
|
"github.com/safing/portmaster/base/dataroot"
|
||||||
"github.com/safing/portmaster/base/log"
|
"github.com/safing/portmaster/base/log"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
_ "github.com/safing/portmaster/service/core/base"
|
_ "github.com/safing/portmaster/service/core/base"
|
||||||
"github.com/safing/portmaster/service/mgr"
|
"github.com/safing/portmaster/service/mgr"
|
||||||
"github.com/safing/portmaster/service/profile/binmeta"
|
"github.com/safing/portmaster/service/profile/binmeta"
|
||||||
|
@ -70,7 +71,7 @@ func prep() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup icon storage location.
|
// Setup icon storage location.
|
||||||
iconsDir := dataroot.Root().ChildDir("databases", 0o0700).ChildDir("icons", 0o0700)
|
iconsDir := dataroot.Root().ChildDir("databases", utils.AdminOnlyPermission).ChildDir("icons", utils.AdminOnlyPermission)
|
||||||
if err := iconsDir.Ensure(); err != nil {
|
if err := iconsDir.Ensure(); err != nil {
|
||||||
return fmt.Errorf("failed to create/check icons directory: %w", err)
|
return fmt.Errorf("failed to create/check icons directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/safing/portmaster/base/api"
|
"github.com/safing/portmaster/base/api"
|
||||||
"github.com/safing/portmaster/base/dataroot"
|
"github.com/safing/portmaster/base/dataroot"
|
||||||
"github.com/safing/portmaster/base/log"
|
"github.com/safing/portmaster/base/log"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
"github.com/safing/portmaster/service/mgr"
|
"github.com/safing/portmaster/service/mgr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ func start() error {
|
||||||
// may seem dangerous, but proper permission on the parent directory provide
|
// may seem dangerous, but proper permission on the parent directory provide
|
||||||
// (some) protection.
|
// (some) protection.
|
||||||
// Processes must _never_ read from this directory.
|
// Processes must _never_ read from this directory.
|
||||||
err := dataroot.Root().ChildDir("exec", 0o0777).Ensure()
|
err := dataroot.Root().ChildDir("exec", utils.PublicWritePermission).Ensure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("ui: failed to create safe exec dir: %s", err)
|
log.Warningf("ui: failed to create safe exec dir: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/safing/portmaster/base/dataroot"
|
"github.com/safing/portmaster/base/dataroot"
|
||||||
"github.com/safing/portmaster/base/log"
|
"github.com/safing/portmaster/base/log"
|
||||||
"github.com/safing/portmaster/base/updater"
|
"github.com/safing/portmaster/base/updater"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
"github.com/safing/portmaster/service/mgr"
|
"github.com/safing/portmaster/service/mgr"
|
||||||
"github.com/safing/portmaster/service/updates/helper"
|
"github.com/safing/portmaster/service/updates/helper"
|
||||||
)
|
)
|
||||||
|
@ -138,7 +139,7 @@ func start() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize
|
// initialize
|
||||||
err = registry.Initialize(dataroot.Root().ChildDir(updatesDirName, 0o0755))
|
err = registry.Initialize(dataroot.Root().ChildDir(updatesDirName, utils.PublicReadPermission))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hectane/go-acl"
|
|
||||||
processInfo "github.com/shirou/gopsutil/process"
|
processInfo "github.com/shirou/gopsutil/process"
|
||||||
"github.com/tevino/abool"
|
"github.com/tevino/abool"
|
||||||
|
|
||||||
|
@ -21,6 +20,7 @@ import (
|
||||||
"github.com/safing/portmaster/base/notifications"
|
"github.com/safing/portmaster/base/notifications"
|
||||||
"github.com/safing/portmaster/base/rng"
|
"github.com/safing/portmaster/base/rng"
|
||||||
"github.com/safing/portmaster/base/updater"
|
"github.com/safing/portmaster/base/updater"
|
||||||
|
"github.com/safing/portmaster/base/utils"
|
||||||
"github.com/safing/portmaster/base/utils/renameio"
|
"github.com/safing/portmaster/base/utils/renameio"
|
||||||
"github.com/safing/portmaster/service/mgr"
|
"github.com/safing/portmaster/service/mgr"
|
||||||
"github.com/safing/portmaster/service/updates/helper"
|
"github.com/safing/portmaster/service/updates/helper"
|
||||||
|
@ -351,17 +351,15 @@ func upgradeBinary(fileToUpgrade string, file *updater.File) error {
|
||||||
|
|
||||||
// check permissions
|
// check permissions
|
||||||
if onWindows {
|
if onWindows {
|
||||||
err = acl.Chmod(fileToUpgrade, 0o0755)
|
_ = utils.SetExecPermission(fileToUpgrade, utils.PublicReadPermission)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to set permissions on %s: %w", fileToUpgrade, err)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
perm := utils.PublicReadPermission
|
||||||
info, err := os.Stat(fileToUpgrade)
|
info, err := os.Stat(fileToUpgrade)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get file info on %s: %w", fileToUpgrade, err)
|
return fmt.Errorf("failed to get file info on %s: %w", fileToUpgrade, err)
|
||||||
}
|
}
|
||||||
if info.Mode() != 0o0755 {
|
if info.Mode() != perm.AsUnixDirExecPermission() {
|
||||||
err := os.Chmod(fileToUpgrade, 0o0755) //nolint:gosec // Set execute permissions.
|
err = utils.SetExecPermission(fileToUpgrade, perm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to set permissions on %s: %w", fileToUpgrade, err)
|
return fmt.Errorf("failed to set permissions on %s: %w", fileToUpgrade, err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue