Override patch policy query (#42322)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #41815 ### Changes - Extracted patch policy creation to `pkg/patch_policy` - Added a `patch_query` column to the `software_installers` table - By default that column is empty, and patch policies will generate with the default query if so - On app manifest ingestion, the appropriate entry in `software_installers` will save the override "patch" query from the manifest in patch_query # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. - [ ] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. - [ ] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [ ] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [ ] QA'd all new/changed functionality manually - Relied on integration test for FMA version pinning ## Database migrations - [x] Checked schema for all modified table for columns that will auto-update timestamps during migration. - [ ] Confirmed that updating the timestamps is acceptable, and will not cause unwanted side effects. - [x] Ensured the correct collation is explicitly set for character columns (`COLLATE utf8mb4_unicode_ci`).
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package patch_policy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
)
|
||||
|
||||
type PolicyData struct {
|
||||
Name string
|
||||
Query string
|
||||
Platform string
|
||||
Description string
|
||||
Resolution string
|
||||
Version string
|
||||
}
|
||||
|
||||
const versionVariable = "$FMA_VERSION"
|
||||
|
||||
var (
|
||||
ErrEmptyQuery = errors.New("query should not be empty")
|
||||
ErrWrongPlatform = errors.New("platform should be darwin or windows")
|
||||
)
|
||||
|
||||
// GenerateFromManifest replaces the $FMA_VERSION variable and checks platform
|
||||
func GenerateFromManifest(p PolicyData) (string, error) {
|
||||
if p.Query == "" {
|
||||
return "", ErrEmptyQuery
|
||||
}
|
||||
// Version is extracted from the manifest so this should be safe to run as an osquery query
|
||||
query := strings.ReplaceAll(p.Query, versionVariable, p.Version)
|
||||
|
||||
switch p.Platform {
|
||||
case "darwin":
|
||||
case "windows":
|
||||
default:
|
||||
return "", ErrWrongPlatform
|
||||
}
|
||||
|
||||
return query, nil
|
||||
}
|
||||
|
||||
// GenerateFromInstaller creates a patch policy with all fields from an installer
|
||||
func GenerateFromInstaller(p PolicyData, installer *fleet.SoftwareInstaller) (*PolicyData, error) {
|
||||
// use the patch policy query from the app manifest if available
|
||||
query := installer.PatchQuery
|
||||
|
||||
if p.Description == "" {
|
||||
p.Description = "Outdated software might introduce security vulnerabilities or compatibility issues."
|
||||
}
|
||||
|
||||
if p.Resolution == "" {
|
||||
p.Resolution = "Install the latest version from self-service."
|
||||
}
|
||||
|
||||
switch installer.Platform {
|
||||
case "darwin":
|
||||
if p.Name == "" {
|
||||
p.Name = fmt.Sprintf("macOS - %s up to date", installer.SoftwareTitle)
|
||||
}
|
||||
if installer.PatchQuery == "" {
|
||||
query = fmt.Sprintf(
|
||||
"SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = '%s' AND version_compare(bundle_short_version, '%s') < 0);",
|
||||
installer.BundleIdentifier,
|
||||
installer.Version,
|
||||
)
|
||||
}
|
||||
case "windows":
|
||||
if p.Name == "" {
|
||||
p.Name = fmt.Sprintf("Windows - %s up to date", installer.SoftwareTitle)
|
||||
}
|
||||
if installer.PatchQuery == "" {
|
||||
// TODO: use upgrade code to improve accuracy?
|
||||
query = fmt.Sprintf(
|
||||
"SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM programs WHERE name = '%s' AND version_compare(version, '%s') < 0);",
|
||||
installer.SoftwareTitle,
|
||||
installer.Version,
|
||||
)
|
||||
}
|
||||
default:
|
||||
return nil, ErrWrongPlatform
|
||||
}
|
||||
|
||||
return &PolicyData{Query: query, Platform: installer.Platform, Name: p.Name, Description: p.Description, Resolution: p.Resolution}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user