[WIP] Updater support for windows

This commit is contained in:
Vladimir Stoilov
2024-09-11 18:52:36 +03:00
parent 8c6eb04292
commit 83ec18f552
11 changed files with 371 additions and 115 deletions

View File

@@ -10,14 +10,13 @@ import (
"github.com/safing/portmaster/service/mgr"
"github.com/safing/portmaster/service/network"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/updates"
)
var useOldKext = false
// start starts the interception.
func startInterception(packets chan packet.Packet) error {
kextFile, err := updates.GetPlatformFile("kext/portmaster-kext.sys")
kextFile, err := module.instance.BinaryUpdates().GetFile("portmaster-kext.sys")
if err != nil {
return fmt.Errorf("interception: could not get kext sys: %s", err)
}
@@ -77,7 +76,6 @@ func startInterception(packets chan packet.Packet) error {
case <-w.Done():
return nil
}
}
})
@@ -95,7 +93,6 @@ func startInterception(packets chan packet.Packet) error {
case <-w.Done():
return nil
}
}
})
@@ -112,7 +109,6 @@ func startInterception(packets chan packet.Packet) error {
case <-w.Done():
return nil
}
}
})
}
@@ -159,5 +155,4 @@ func GetKextVersion() (string, error) {
}
return version.String(), nil
}
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/safing/portmaster/base/log"
"github.com/safing/portmaster/service/mgr"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/updates"
)
// Interception is the packet interception module.
@@ -97,4 +98,6 @@ func New(instance instance) (*Interception, error) {
return module, nil
}
type instance interface{}
type instance interface {
BinaryUpdates() *updates.Updates
}

View File

@@ -62,6 +62,9 @@ func GetKextServiceHandle() windows.Handle {
// Stop intercepting.
func Stop() error {
if kextFile == nil {
return fmt.Errorf("kextfile is nil")
}
// Prepare kernel for shutdown
err := shutdownRequest()
if err != nil {

View File

@@ -3,6 +3,7 @@ package service
import (
"context"
"fmt"
go_runtime "runtime"
"sync/atomic"
"time"
@@ -47,23 +48,6 @@ import (
"github.com/safing/portmaster/spn/terminal"
)
var binaryUpdateIndex = registry.UpdateIndex{
Directory: "/usr/lib/portmaster",
DownloadDirectory: "/var/lib/portmaster/new_bin",
Ignore: []string{"databases", "intel", "config.json"},
IndexURLs: []string{"http://localhost:8000/test-binary.json"},
IndexFile: "bin-index.json",
AutoApply: false,
}
var intelUpdateIndex = registry.UpdateIndex{
Directory: "/var/lib/portmaster/intel",
DownloadDirectory: "/var/lib/portmaster/new_intel",
IndexURLs: []string{"http://localhost:8000/test-intel.json"},
IndexFile: "intel-index.json",
AutoApply: true,
}
// Instance is an instance of a Portmaster service.
type Instance struct {
ctx context.Context
@@ -121,6 +105,48 @@ type Instance struct {
// New returns a new Portmaster service instance.
func New(svcCfg *ServiceConfig) (*Instance, error) { //nolint:maintidx
var binaryUpdateIndex registry.UpdateIndex
var intelUpdateIndex registry.UpdateIndex
if go_runtime.GOOS == "windows" {
binaryUpdateIndex = registry.UpdateIndex{
Directory: "C:/Program Files/Portmaster/binary",
DownloadDirectory: "C:/Program Files/Portmaster/new_binary",
PurgeDirectory: "C:/Program Files/Portmaster/old_binary",
Ignore: []string{"databases", "intel", "config.json"},
IndexURLs: []string{"http://192.168.88.11:8000/test-binary.json"},
IndexFile: "bin-index.json",
AutoApply: false,
}
intelUpdateIndex = registry.UpdateIndex{
Directory: "C:/Program Files/Portmaster/intel",
DownloadDirectory: "C:/Program Files/Portmaster/new_intel",
PurgeDirectory: "C:/Program Files/Portmaster/old_intel",
IndexURLs: []string{"http://192.168.88.11:8000/test-intel.json"},
IndexFile: "intel-index.json",
AutoApply: true,
}
} else if go_runtime.GOOS == "linux" {
binaryUpdateIndex = registry.UpdateIndex{
Directory: "/usr/lib/portmaster",
DownloadDirectory: "/var/lib/portmaster/new_bin",
PurgeDirectory: "/var/lib/portmaster/old_bin",
Ignore: []string{"databases", "intel", "config.json"},
IndexURLs: []string{"http://localhost:8000/test-binary.json"},
IndexFile: "bin-index.json",
AutoApply: false,
}
intelUpdateIndex = registry.UpdateIndex{
Directory: "/var/lib/portmaster/intel",
DownloadDirectory: "/var/lib/portmaster/new_intel",
PurgeDirectory: "/var/lib/portmaster/intel_bin",
IndexURLs: []string{"http://localhost:8000/test-intel.json"},
IndexFile: "intel-index.json",
AutoApply: true,
}
}
// Create instance to pass it to modules.
instance := &Instance{}
instance.ctx, instance.cancelCtx = context.WithCancel(context.Background())

View File

@@ -12,6 +12,7 @@ import (
"net/http"
"os"
"path/filepath"
"runtime"
"time"
"github.com/safing/portmaster/base/log"
@@ -19,6 +20,8 @@ import (
const MaxUnpackSize = 1 << 30 // 2^30 == 1GB
const current_platform = runtime.GOOS + "_" + runtime.GOARCH
type Artifact struct {
Filename string `json:"Filename"`
SHA256 string `json:"SHA256"`
@@ -107,6 +110,11 @@ func checkIfFileIsValid(filename string, artifact Artifact) (bool, error) {
}
func processArtifact(client *http.Client, artifact Artifact, filePath string) error {
// Skip artifacts not meant for this machine.
if artifact.Platform != "" && artifact.Platform != current_platform {
return nil
}
providedHash, err := hex.DecodeString(artifact.SHA256)
if err != nil || len(providedHash) != sha256.Size {
return fmt.Errorf("invalid provided hash %s: %w", artifact.SHA256, err)
@@ -149,6 +157,7 @@ func processArtifact(client *http.Client, artifact Artifact, filePath string) er
if err != nil {
return fmt.Errorf("failed to write to file: %w", err)
}
file.Close()
// Rename
err = os.Rename(tmpFilename, filePath)

View File

@@ -125,7 +125,7 @@ func (reg *Registry) DownloadUpdates() error {
// ApplyUpdates removes the current binary folder and replaces it with the downloaded one.
func (reg *Registry) ApplyUpdates() error {
// Create purge dir.
err := os.MkdirAll(filepath.Dir(reg.updateIndex.PurgeDirectory), defaultDirMode)
err := os.MkdirAll(reg.updateIndex.PurgeDirectory, defaultDirMode)
if err != nil {
return fmt.Errorf("failed to create directory: %w", err)
}
@@ -198,7 +198,7 @@ func deleteUnfinishedDownloads(rootDir string) error {
// Check if the current file has the specified extension
if !info.IsDir() && strings.HasSuffix(info.Name(), ".download") {
log.Warningf("updates deleting unfinished: %s\n", path)
log.Warningf("updates: deleting unfinished: %s\n", path)
err := os.Remove(path)
if err != nil {
return fmt.Errorf("failed to delete file %s: %w", path, err)