diff --git a/cmds/portmaster-start/main.go b/cmds/portmaster-start/main.go index 5b0ad97c..196afc55 100644 --- a/cmds/portmaster-start/main.go +++ b/cmds/portmaster-start/main.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log" + "net/url" "os" "os/signal" "path/filepath" @@ -24,11 +25,13 @@ import ( var ( dataDir string - staging bool maxRetries int dataRoot *utils.DirStructure logsRoot *utils.DirStructure + updateURLFlag string + userAgentFlag string + // Create registry. registry = &updater.ResourceRegistry{ Name: "updates", @@ -67,8 +70,8 @@ func init() { flags := rootCmd.PersistentFlags() { flags.StringVar(&dataDir, "data", "", "Configures the data directory. Alternatively, this can also be set via the environment variable PORTMASTER_DATA.") - flags.StringVar(®istry.UserAgent, "update-agent", "Start", "Sets the user agent for requests to the update server") - flags.BoolVar(&staging, "staging", false, "Deprecated, configure in settings instead.") + flags.StringVar(&updateURLFlag, "update-server", "", "Set an alternative update server (full URL)") + flags.StringVar(&userAgentFlag, "update-agent", "", "Set an alternative user agent for requests to the update server") flags.IntVar(&maxRetries, "max-retries", 5, "Maximum number of retries when starting a Portmaster component") flags.BoolVar(&stdinSignals, "input-signals", false, "Emulate signals using stdin.") _ = rootCmd.MarkPersistentFlagDirname("data") @@ -137,6 +140,25 @@ func initCobra() { } func configureRegistry(mustLoadIndex bool) error { + // Check if update server URL supplied via flag is a valid URL. + if updateURLFlag != "" { + u, err := url.Parse(updateURLFlag) + if err != nil { + return fmt.Errorf("supplied update server URL is invalid: %w", err) + } + if u.Scheme != "https" { + return errors.New("supplied update server URL must use HTTPS") + } + } + + // Override values from flags. + if userAgentFlag != "" { + registry.UserAgent = userAgentFlag + } + if updateURLFlag != "" { + registry.UpdateURLs = []string{updateURLFlag} + } + // If dataDir is not set, check the environment variable. if dataDir == "" { dataDir = os.Getenv("PORTMASTER_DATA") diff --git a/cmds/portmaster-start/update.go b/cmds/portmaster-start/update.go index e04508c3..cea5b157 100644 --- a/cmds/portmaster-start/update.go +++ b/cmds/portmaster-start/update.go @@ -134,10 +134,8 @@ func logProgress(state *updater.RegistryState) { len(downloadDetails.Resources), downloadDetails.Resources[downloadDetails.FinishedUpTo], ) - } else { - if state.Updates.LastDownloadAt == nil { - log.Println("finalizing downloads") - } + } else if state.Updates.LastDownloadAt == nil { + log.Println("finalizing downloads") } } } diff --git a/updates/main.go b/updates/main.go index 8ae81af5..df7cf277 100644 --- a/updates/main.go +++ b/updates/main.go @@ -2,8 +2,10 @@ package updates import ( "context" + "errors" "flag" "fmt" + "net/url" "runtime" "time" @@ -41,9 +43,11 @@ const ( ) var ( - module *modules.Module - registry *updater.ResourceRegistry - userAgentFromFlag string + module *modules.Module + registry *updater.ResourceRegistry + + userAgentFromFlag string + updateServerFromFlag string updateTask *modules.Task updateASAP bool @@ -59,6 +63,11 @@ var ( // fetching resources from the update server. UserAgent = fmt.Sprintf("Portmaster (%s %s)", runtime.GOOS, runtime.GOARCH) + // DefaultUpdateURLs defines the default base URLs of the update server. + DefaultUpdateURLs = []string{ + "https://updates.safing.io", + } + // DisableSoftwareAutoUpdate specifies whether software updates should be disabled. // This is used on Android, as it will never require binary updates. DisableSoftwareAutoUpdate = false @@ -75,10 +84,8 @@ func init() { module.RegisterEvent(VersionUpdateEvent, true) module.RegisterEvent(ResourceUpdateEvent, true) - flag.StringVar(&userAgentFromFlag, "update-agent", "", "set the user agent for requests to the update server") - - var dummy bool - flag.BoolVar(&dummy, "staging", false, "deprecated, configure in settings instead") + flag.StringVar(&updateServerFromFlag, "update-server", "", "set an alternative update server (full URL)") + flag.StringVar(&userAgentFromFlag, "update-agent", "", "set an alternative user agent for requests to the update server") } func prep() error { @@ -86,6 +93,17 @@ func prep() error { return err } + // Check if update server URL supplied via flag is a valid URL. + if updateServerFromFlag != "" { + u, err := url.Parse(updateServerFromFlag) + if err != nil { + return fmt.Errorf("supplied update server URL is invalid: %w", err) + } + if u.Scheme != "https" { + return errors.New("supplied update server URL must use HTTPS") + } + } + return registerAPIEndpoints() } @@ -104,10 +122,8 @@ func start() error { // create registry registry = &updater.ResourceRegistry{ - Name: ModuleName, - UpdateURLs: []string{ - "https://updates.safing.io", - }, + Name: ModuleName, + UpdateURLs: DefaultUpdateURLs, UserAgent: UserAgent, MandatoryUpdates: helper.MandatoryUpdates(), AutoUnpack: helper.AutoUnpackUpdates(), @@ -115,10 +131,13 @@ func start() error { DevMode: devMode(), Online: true, } + // Override values from flags. if userAgentFromFlag != "" { - // override with flag value registry.UserAgent = userAgentFromFlag } + if updateServerFromFlag != "" { + registry.UpdateURLs = []string{updateServerFromFlag} + } // pre-init state updateStateExport, err := LoadStateExport()