mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-09-15 21:00:27 +00:00
boxdd: Add custom working directory support
This commit is contained in:
@@ -2,9 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
@@ -29,10 +27,12 @@ func preparePlatformWorkingDirectory() error {
|
|||||||
if listenAddress != "" {
|
if listenAddress != "" {
|
||||||
return os.MkdirAll(workingDirectory, 0o700)
|
return os.MkdirAll(workingDirectory, 0o700)
|
||||||
}
|
}
|
||||||
if !strings.EqualFold(filepath.Clean(workingDirectory), filepath.Clean(defaultServiceWorkingDirectory)) {
|
serviceWorkingDirectory, err := resolveWindowsServiceWorkingDirectory(workingDirectory)
|
||||||
return E.New("the Windows service working directory must be ", defaultServiceWorkingDirectory)
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return ensureWindowsWorkingDirectory(workingDirectory)
|
workingDirectory = serviceWorkingDirectory
|
||||||
|
return ensureWindowsWorkingDirectory(serviceWorkingDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
type windowsService struct{}
|
type windowsService struct{}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -65,19 +64,24 @@ func serviceInstall() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return E.Cause(err, "get executable path")
|
return E.Cause(err, "get executable path")
|
||||||
}
|
}
|
||||||
if !strings.EqualFold(filepath.Clean(commandServiceFlagWorkingDirectory), filepath.Clean(defaultServiceWorkingDirectory)) {
|
serviceWorkingDirectory, err := resolveWindowsServiceWorkingDirectory(commandServiceFlagWorkingDirectory)
|
||||||
return E.New("the Windows service working directory must be ", defaultServiceWorkingDirectory)
|
if err != nil {
|
||||||
|
return E.Cause(err, "validate working directory")
|
||||||
}
|
}
|
||||||
executablePath, err = secureWindowsInstallation(executablePath, commandServiceFlagAllowUnsafeInstallation)
|
executablePath, err = secureWindowsInstallation(executablePath, commandServiceFlagAllowUnsafeInstallation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return E.Cause(err, "secure installation")
|
return E.Cause(err, "secure installation")
|
||||||
}
|
}
|
||||||
|
err = ensureWindowsWorkingDirectory(serviceWorkingDirectory)
|
||||||
|
if err != nil {
|
||||||
|
return E.Cause(err, "secure working directory")
|
||||||
|
}
|
||||||
manager, err := mgr.Connect()
|
manager, err := mgr.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return E.Cause(err, "connect to service manager")
|
return E.Cause(err, "connect to service manager")
|
||||||
}
|
}
|
||||||
defer manager.Disconnect()
|
defer manager.Disconnect()
|
||||||
arguments := []string{"run", "--working-directory", defaultServiceWorkingDirectory}
|
arguments := []string{"run", "--working-directory", serviceWorkingDirectory}
|
||||||
config := mgr.Config{
|
config := mgr.Config{
|
||||||
DisplayName: serviceDisplayName,
|
DisplayName: serviceDisplayName,
|
||||||
Description: serviceDescriptionText,
|
Description: serviceDescriptionText,
|
||||||
@@ -132,11 +136,6 @@ func serviceInstall() error {
|
|||||||
rollback()
|
rollback()
|
||||||
return E.Cause(err, "secure service")
|
return E.Cause(err, "secure service")
|
||||||
}
|
}
|
||||||
err = ensureWindowsWorkingDirectory(defaultServiceWorkingDirectory)
|
|
||||||
if err != nil {
|
|
||||||
rollback()
|
|
||||||
return E.Cause(err, "secure working directory")
|
|
||||||
}
|
|
||||||
err = eventlog.InstallAsEventCreate(serviceName, eventlog.Error|eventlog.Warning|eventlog.Info)
|
err = eventlog.InstallAsEventCreate(serviceName, eventlog.Error|eventlog.Warning|eventlog.Info)
|
||||||
if err != nil && !strings.Contains(err.Error(), "already exists") {
|
if err != nil && !strings.Contains(err.Error(), "already exists") {
|
||||||
rollback()
|
rollback()
|
||||||
|
|||||||
@@ -336,6 +336,40 @@ func validateFixedNTFSVolume(path string) (string, error) {
|
|||||||
return filepath.Clean(volumePath), nil
|
return filepath.Clean(volumePath), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveWindowsServiceWorkingDirectory(path string) (string, error) {
|
||||||
|
if path == "" {
|
||||||
|
return "", E.New("missing daemon working directory")
|
||||||
|
}
|
||||||
|
absolutePath, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", E.Cause(err, "resolve daemon working directory")
|
||||||
|
}
|
||||||
|
cleanPath := filepath.Clean(absolutePath)
|
||||||
|
parentPath := filepath.Dir(cleanPath)
|
||||||
|
parentAttributes, err := windowsFileAttributes(parentPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", E.Cause(err, "query daemon working directory parent")
|
||||||
|
}
|
||||||
|
if parentAttributes&windows.FILE_ATTRIBUTE_DIRECTORY == 0 {
|
||||||
|
return "", E.New("daemon working directory parent is not a directory")
|
||||||
|
}
|
||||||
|
if parentAttributes&windows.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||||
|
return "", E.New("daemon working directory parent is a reparse point")
|
||||||
|
}
|
||||||
|
volumeRoot, err := validateFixedNTFSVolume(parentPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", E.Cause(err, "validate daemon working directory volume")
|
||||||
|
}
|
||||||
|
if strings.EqualFold(cleanPath, filepath.Clean(volumeRoot)) {
|
||||||
|
return "", E.New("daemon working directory must not be a volume root")
|
||||||
|
}
|
||||||
|
err = validateInstallationAncestors(parentPath, volumeRoot, true)
|
||||||
|
if err != nil {
|
||||||
|
return "", E.Cause(err, "validate daemon working directory ancestors")
|
||||||
|
}
|
||||||
|
return cleanPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
func validateInstallationAncestors(path string, volumeRoot string, validatePermissions bool) error {
|
func validateInstallationAncestors(path string, volumeRoot string, validatePermissions bool) error {
|
||||||
currentPath := filepath.Clean(path)
|
currentPath := filepath.Clean(path)
|
||||||
cleanVolumeRoot := filepath.Clean(volumeRoot)
|
cleanVolumeRoot := filepath.Clean(volumeRoot)
|
||||||
|
|||||||
Reference in New Issue
Block a user