ensure file permissions of the nudge config file are consistent (#11374)

For #11218, In the initial implementation of the feature, we used to
launch Nudge as a root, so setting the permissions of the config file to
0600 was okay.

As part of the fix for #10044, we now launch Nudge as the current user
(which is also recommended in the Nudge wiki), but previous
installations of the beta version (probably only Fleeties using Dogfood)
still have the configuration file with restrictive permissions, so Nudge
wasn't able to read the config when launched as a user.

This is kind of hidden because `os.WriteFile` takes a permission
arugment, but it's only used if it's writing the file for the first
time.
This commit is contained in:
Roberto Dip 2023-04-27 10:22:42 -03:00 committed by GitHub
parent a23d208b1d
commit 35e06fa1ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 2 deletions

View file

@ -0,0 +1 @@
* Fixed an issue preventing Nudge to read the configuration file delivered by Fleet on some installations. This only affects you if Nudge was enabled and configured on a host using Orbit v1.8.0

View file

@ -17,6 +17,7 @@ import (
)
const nudgeConfigFile = "nudge-config.json"
const nudgeConfigFileMode = os.FileMode(constant.DefaultWorldReadableFileMode)
// NudgeConfigFetcher is a kind of middleware that wraps an OrbitConfigFetcher and a Runner.
// It checks the config supplied by the wrapped OrbitConfigFetcher to detects whether the Fleet
@ -135,6 +136,17 @@ func (n *NudgeConfigFetcher) configure(nudgeCfg fleet.NudgeConfig) error {
return err
}
// ensure the config file has the right permissions, a call to
// WriteFile preserves existing permissions if the file already exists,
// and previous versions of orbit set the permissions of this file to
// constant.DefaultFileMode.
if fileInfo.Mode() != nudgeConfigFileMode {
log.Info().Msgf("%s config file had wrong permissions (%v) setting permissions to %v", cfgFile, fileInfo.Mode(), nudgeConfigFileMode)
if err := os.Chmod(cfgFile, nudgeConfigFileMode); err != nil {
return fmt.Errorf("ensuring permissions of config file, chmod %q: %w", cfgFile, err)
}
}
// this not only an optimization, but mostly a safeguard: if the file
// has been tampered and contains very large contents, we don't
// want to load them into memory.

View file

@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/fleetdm/fleet/v4/orbit/pkg/constant"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
@ -45,6 +46,7 @@ func (s *nudgeTestSuite) TestNudgeConfigFetcherAddNudge() {
Interval: interval,
runNudgeFn: runNudgeFn,
})
configPath := filepath.Join(tmpDir, nudgeConfigFile)
// nudge is not added to targets if nudge config is not present
cfg.NudgeConfig = nil
@ -105,7 +107,7 @@ func (s *nudgeTestSuite) TestNudgeConfigFetcherAddNudge() {
gotCfg, err = f.GetConfig()
require.NoError(t, err)
require.Equal(t, cfg, gotCfg)
configBytes, err := os.ReadFile(filepath.Join(tmpDir, nudgeConfigFile))
configBytes, err := os.ReadFile(configPath)
require.NoError(t, err)
var savedConfig fleet.NudgeConfig
err = json.Unmarshal(configBytes, &savedConfig)
@ -117,7 +119,24 @@ func (s *nudgeTestSuite) TestNudgeConfigFetcherAddNudge() {
gotCfg, err = f.GetConfig()
require.NoError(t, err)
require.Equal(t, cfg, gotCfg)
configBytes, err = os.ReadFile(filepath.Join(tmpDir, nudgeConfigFile))
configBytes, err = os.ReadFile(configPath)
require.NoError(t, err)
savedConfig = fleet.NudgeConfig{}
err = json.Unmarshal(configBytes, &savedConfig)
require.NoError(t, err)
require.Equal(t, cfg.NudgeConfig, &savedConfig)
// config permissions are always validated and set to the right value
err = os.Chmod(configPath, constant.DefaultFileMode)
require.NoError(t, err)
gotCfg, err = f.GetConfig()
require.NoError(t, err)
require.Equal(t, cfg, gotCfg)
fileInfo, err := os.Stat(configPath)
require.NoError(t, err)
require.Equal(t, fileInfo.Mode(), nudgeConfigFileMode)
configBytes, err = os.ReadFile(configPath)
require.NoError(t, err)
savedConfig = fleet.NudgeConfig{}
err = json.Unmarshal(configBytes, &savedConfig)