Revert "Initial Windows support (#10)" (#11)

This reverts commit 7767da94e8.

This was accidentally force-pushed before merging and included the incorrect changes.
This commit is contained in:
Zach Wasserman 2021-04-16 17:24:11 -07:00 committed by GitHub
parent 7767da94e8
commit 3d1cf985a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 21 additions and 438 deletions

View file

@ -11,7 +11,6 @@ import (
"strings"
"time"
"github.com/dgraph-io/badger/v2"
"github.com/fleetdm/orbit/pkg/certificate"
"github.com/fleetdm/orbit/pkg/constant"
"github.com/fleetdm/orbit/pkg/database"
@ -27,6 +26,7 @@ import (
)
const (
certPath = "/tmp/fleet.pem"
defaultRootDir = "/var/lib/orbit"
)
@ -143,18 +143,9 @@ func main() {
return errors.Wrap(err, "initialize root dir")
}
dbPath := filepath.Join(c.String("root-dir"), "orbit.db")
db, err := database.Open(dbPath)
db, err := database.Open(filepath.Join(c.String("root-dir"), "orbit.db"))
if err != nil {
if errors.Is(err, badger.ErrTruncateNeeded) {
db, err = database.OpenTruncate(dbPath)
if err != nil {
return err
}
log.Warn().Msg("Open badger required truncate. Possible data loss.")
} else {
return err
}
return err
}
defer func() {
if err := db.Close(); err != nil {
@ -238,8 +229,7 @@ func main() {
)
// Write cert that proxy uses
certPath := filepath.Join(opt.RootDirectory, "insecure-cert.pem")
err = ioutil.WriteFile(filepath.Join(opt.RootDirectory, "insecure-cert.pem"), []byte(insecure.ServerCert), os.ModePerm)
err = ioutil.WriteFile(certPath, []byte(insecure.ServerCert), os.ModePerm)
if err != nil {
return errors.Wrap(err, "write server cert")
}

View file

@ -129,10 +129,8 @@ func main() {
return packaging.BuildDeb(opt)
case "rpm":
return packaging.BuildRPM(opt)
case "msi":
return packaging.BuildMSI(opt)
default:
return errors.New("type must be one of ('pkg', 'deb', 'rpm', 'msi')")
return errors.New("type must be one of ('pkg', 'deb', 'rpm')")
}
}

View file

@ -22,7 +22,7 @@ type BadgerDB struct {
closeChan chan struct{}
}
// Open opens (initializing if necessary) a Badger database at the specified
// Open opens (initializing if necessary) a new Badger database at the specified
// path. Users must close the DB with Close().
func Open(path string) (*BadgerDB, error) {
// DefaultOptions sets synchronous writes to true (maximum data integrity).
@ -38,26 +38,6 @@ func Open(path string) (*BadgerDB, error) {
return b, nil
}
// OpenTruncate opens (initializing and/or truncating if necessary) a Badger
// database at the specified path. Users must close the DB with Close().
//
// Prefer Open in the general case, but after a bad shutdown it may be necessary
// to call OpenTruncate. This may cause data loss. Detect this situation by
// looking for badger.ErrTruncateNeeded.
func OpenTruncate(path string) (*BadgerDB, error) {
// DefaultOptions sets synchronous writes to true (maximum data integrity).
// TODO implement logging?
db, err := badger.Open(badger.DefaultOptions(path).WithLogger(nil).WithTruncate(true))
if err != nil {
return nil, errors.Wrapf(err, "open badger with truncate %s", path)
}
b := &BadgerDB{DB: db}
b.startBackgroundCompaction()
return b, nil
}
// startBackgroundCompaction starts a background loop that will call the
// compaction method on the database. Badger does not do this automatically, so
// we need to be sure to do so here (or elsewhere).

View file

@ -156,6 +156,20 @@ func writeScripts(opt Options, rootPath string) error {
return nil
}
func writeSecret(opt Options, orbitRoot string) error {
// Enroll secret
path := filepath.Join(orbitRoot, "secret")
if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil {
return errors.Wrap(err, "mkdir")
}
if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil {
return errors.Wrap(err, "write file")
}
return nil
}
func writeLaunchd(opt Options, rootPath string) error {
// launchd is the service mechanism on macOS
path := filepath.Join(rootPath, "Library", "LaunchDaemons", "com.fleetdm.orbit.plist")

View file

@ -71,7 +71,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err
{{ if .Insecure }}<key>ORBIT_INSECURE</key><string>true</string>{{ end }}
{{ if .FleetURL }}<key>ORBIT_FLEET_URL</key><string>{{ .FleetURL }}</string>{{ end }}
{{ if .FleetCertificate }}<key>ORBIT_FLEET_CERTIFICATE</key><string>/var/lib/orbit/fleet.pem</string>{{ end }}
{{ if .EnrollSecret }}<key>ORBIT_ENROLL_SECRET_PATH</key><string>/var/lib/orbit/secret.txt</string>{{ end }}
{{ if .EnrollSecret }}<key>ORBIT_ENROLL_SECRET_PATH</key><string>/var/lib/orbit/secret</string>{{ end }}
{{ if .Debug }}<key>ORBIT_DEBUG</key><string>true</string>{{ end }}
</dict>
<key>KeepAlive</key><true/>

View file

@ -3,11 +3,9 @@ package packaging
import (
"io"
"io/ioutil"
"os"
"path/filepath"
"github.com/fleetdm/orbit/pkg/constant"
"github.com/fleetdm/orbit/pkg/update"
"github.com/fleetdm/orbit/pkg/update/filestore"
"github.com/pkg/errors"
@ -100,17 +98,3 @@ func initializeUpdates(updateOpt update.Options) error {
return nil
}
// writeSecret writes the enroll secret to a text file
func writeSecret(opt Options, orbitRoot string) error {
path := filepath.Join(orbitRoot, "secret.txt")
if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil {
return errors.Wrap(err, "mkdir")
}
if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil {
return errors.Wrap(err, "write file")
}
return nil
}

View file

@ -1,104 +0,0 @@
package packaging
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/fleetdm/orbit/pkg/constant"
"github.com/fleetdm/orbit/pkg/packaging/wix"
"github.com/fleetdm/orbit/pkg/update"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
// BuildMSI builds a Windows .msi.
func BuildMSI(opt Options) error {
// Initialize directories
tmpDir, err := ioutil.TempDir("", "orbit-package")
if err != nil {
return errors.Wrap(err, "failed to create temp dir")
}
defer os.RemoveAll(tmpDir)
log.Debug().Str("path", tmpDir).Msg("created temp dir")
filesystemRoot := filepath.Join(tmpDir, "root")
if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil {
return errors.Wrap(err, "create root dir")
}
orbitRoot := filesystemRoot
if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil {
return errors.Wrap(err, "create orbit dir")
}
// Initialize autoupdate metadata
updateOpt := update.DefaultOptions
updateOpt.Platform = "windows"
updateOpt.RootDirectory = orbitRoot
updateOpt.OrbitChannel = opt.OrbitChannel
updateOpt.OsquerydChannel = opt.OsquerydChannel
updateOpt.ServerURL = opt.UpdateURL
if opt.UpdateRoots != "" {
updateOpt.RootKeys = opt.UpdateRoots
}
if err := initializeUpdates(updateOpt); err != nil {
return errors.Wrap(err, "initialize updates")
}
// Write files
if err := writeSecret(opt, orbitRoot); err != nil {
return errors.Wrap(err, "write enroll secret")
}
if err := writeWixFile(opt, tmpDir); err != nil {
return errors.Wrap(err, "write wix file")
}
if err := wix.Heat(tmpDir); err != nil {
return errors.Wrap(err, "package root files")
}
if err := wix.TransformHeat(filepath.Join(tmpDir, "heat.wxs")); err != nil {
return errors.Wrap(err, "transform heat")
}
if err := wix.Candle(tmpDir); err != nil {
return errors.Wrap(err, "build package")
}
if err := wix.Light(tmpDir); err != nil {
return errors.Wrap(err, "build package")
}
filename := fmt.Sprintf("orbit-osquery_%s.msi", opt.Version)
if err := os.Rename(filepath.Join(tmpDir, "orbit.msi"), filename); err != nil {
return errors.Wrap(err, "rename msi")
}
log.Info().Str("path", filename).Msg("wrote msi package")
return nil
}
func writeWixFile(opt Options, rootPath string) error {
// PackageInfo is metadata for the pkg
path := filepath.Join(rootPath, "main.wxs")
if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil {
return errors.Wrap(err, "mkdir")
}
var contents bytes.Buffer
if err := windowsWixTemplate.Execute(&contents, opt); err != nil {
return errors.Wrap(err, "execute template")
}
if err := ioutil.WriteFile(path, contents.Bytes(), 0o666); err != nil {
return errors.Wrap(err, "write file")
}
return nil
}

View file

@ -1,78 +0,0 @@
package packaging
import "text/template"
// Partially adapted from Launcher's wix XML in
// https://github.com/kolide/launcher/blob/master/pkg/packagekit/internal/assets/main.wxs.
var windowsWixTemplate = template.Must(template.New("").Option("missingkey=error").Parse(
`<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product
Id="C2C2437D-0562-465E-A0BB-2C4484025BD6"
Name="Orbit osquery"
Language="1033"
Version="{{.Version}}"
Manufacturer="Fleet Device Management (fleetdm.com)"
UpgradeCode="B681CB20-107E-428A-9B14-2D3C1AFED244" >
<Package
Id="*"
Keywords='orbit osquery'
Description="Orbit osquery"
InstallerVersion="500"
Compressed="yes"
InstallScope="perMachine"
InstallPrivileges="elevated"
Languages="1033" />
<MediaTemplate EmbedCab="yes" />
<MajorUpgrade AllowDowngrades="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="ORBITROOT" Name="Orbit">
<Component Id="C_ORBITROOT" Guid="A7DFD09E-2D2B-4535-A04F-5D4DE90F3863">
<CreateFolder>
<PermissionEx Sddl="O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)" />
</CreateFolder>
</Component>
<Directory Id="ORBITBIN" Name="bin">
<Component Id="C_ORBITBIN" Guid="AF347B4E-B84B-4DD4-9C4D-133BE17B613D">
<CreateFolder>
<PermissionEx Sddl="O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)" />
</CreateFolder>
<File Source="root\bin\orbit\windows\stable\orbit.exe">
<PermissionEx Sddl="O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)" />
</File>
<ServiceInstall
Name="Orbit osquery"
Account="NT AUTHORITY\SYSTEM"
ErrorControl="ignore"
Start="auto"
Type="ownProcess"
Arguments='--root-dir "[ORBITROOT]." {{ if .FleetURL }}--fleet-url "{{ .FleetURL }}"{{ end }} {{ if .EnrollSecret }}--enroll-secret-path "[ORBITROOT]secret.txt"{{ end }} {{if .Insecure }}--insecure{{ end }} {{ if .UpdateURL }}--update-url "{{ .UpdateURL }}"{{ end }}'
>
</ServiceInstall>
<ServiceControl
Id="StartOrbitService"
Name="Orbit osquery"
Start="install"
Stop="both"
Remove="uninstall"
/>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id="Orbit" Title="Orbit osquery" Level="1" Display="hidden">
<ComponentGroupRef Id="OrbitFiles" />
<ComponentRef Id="C_ORBITBIN" />
<ComponentRef Id="C_ORBITROOT" />
</Feature>
</Product>
</Wix>
`))

View file

@ -1,113 +0,0 @@
package wix
import (
"bytes"
"encoding/xml"
"io/ioutil"
"github.com/pkg/errors"
)
type node struct {
XMLName xml.Name
Attrs attrs `xml:",any,attr"`
Content string `xml:",chardata"`
Children []*node `xml:",any"`
}
type attrs []*xml.Attr
// Get the value of the attr with the provided name, otherwise returning an
// empty string.
func (a attrs) Get(name string) string {
for _, attr := range a {
if attr.Name.Local == name {
return attr.Value
}
}
return ""
}
func xmlAttr(name, value string) *xml.Attr {
return &xml.Attr{Name: xml.Name{Local: name}, Value: value}
}
func xmlNode(name string, attrs ...*xml.Attr) *node {
return &node{
XMLName: xml.Name{Local: name},
Attrs: attrs,
}
}
func TransformHeat(path string) error {
contents, err := ioutil.ReadFile(path)
if err != nil {
return errors.Wrap(err, "read file")
}
// Eliminate line feeds (they cause extra junk in the result)
contents = bytes.ReplaceAll(contents, []byte("\r"), []byte(""))
var n node
if err := xml.Unmarshal(contents, &n); err != nil {
return errors.Wrap(err, "unmarshal xml")
}
stack := []*node{}
if err := transform(&n, &stack); err != nil {
return errors.Wrap(err, "in transform")
}
contents, err = xml.MarshalIndent(n, "", " ")
if err != nil {
return errors.Wrap(err, "marshal xml")
}
if err := ioutil.WriteFile(path, contents, 0o600); err != nil {
return errors.Wrap(err, "write file")
}
return nil
}
func transform(cur *node, stack *[]*node) error {
// Clear namespace on all elements (generates unnecessarily noisy output if
// this is not done).
cur.XMLName.Space = ""
// Change permissions for all files
if cur.XMLName.Local == "File" {
// This SDDL copied directly from osqueryd.exe after a regular
// osquery MSI install. We assume that osquery is getting the
// permissions correct and use exactly the same for our files.
// Using this cryptic string seems to be the only way to disable
// permission inheritance in a WiX package, so we may not have
// any option for something more readable.
sddl := "O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)"
if cur.Attrs.Get("Name") == "secret.txt" {
// This SDDL copied from properly configured file on a Windows
// 10 machine. Permissions are same as below but with read
// access removed for regular users.
sddl = "O:SYG:SYD:PAI(A;;FA;;;SY)(A;;FA;;;BA)"
}
cur.Children = append(cur.Children, xmlNode(
"PermissionEx",
xmlAttr("Sddl", sddl),
))
}
// push current node onto stack
*stack = append(*stack, cur)
// Recursively walk the children
for _, child := range cur.Children {
if err := transform(child, stack); err != nil {
return err
}
}
// pop current node from stack
*stack = (*stack)[:len(*stack)-1]
return nil
}

View file

@ -1,88 +0,0 @@
// Package wix runs the WiX packaging tools via Docker.
//
// WiX's documentation is available at https://wixtoolset.org/.
package wix
import (
"os"
"os/exec"
"github.com/pkg/errors"
)
const (
directoryReference = "ORBITROOT"
)
// Heat runs the WiX Heat command on the provided directory.
//
// The Heat command creates XML fragments allowing WiX to include the entire
// directory. See
// https://wixtoolset.org/documentation/manual/v3/overview/heat.html.
func Heat(path string) error {
cmd := exec.Command(
"docker", "run", "--rm", "--platform", "linux/386",
"--volume", path+":/wix", // mount volume
"dactiv/wix:latest", // image name
"heat", "dir", "root", // command in image
"-out", "heat.wxs",
"-gg", "-g1", // generate UUIDs (required by wix)
"-cg", "OrbitFiles", // set ComponentGroup name
"-scom", "-sfrag", "-srd", "-sreg", // suppress unneccesary generated items
"-dr", directoryReference, // set reference name
"-ke", // keep empty directories
)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if err := cmd.Run(); err != nil {
return errors.Wrap(err, "heat failed")
}
return nil
}
// Candle runs the WiX Candle command on the provided directory.
//
// See
// https://wixtoolset.org/documentation/manual/v3/overview/candle.html.
func Candle(path string) error {
cmd := exec.Command(
"docker", "run", "--rm", "--platform", "linux/386",
"--volume", path+":/wix", // mount volume
"dactiv/wix:latest", // image name
"candle", "heat.wxs", "main.wxs", // command in image
"-ext", "WixUtilExtension",
"-arch", "x64",
)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if err := cmd.Run(); err != nil {
return errors.Wrap(err, "candle failed")
}
return nil
}
// Light runs the WiX Light command on the provided directory.
//
// See
// https://wixtoolset.org/documentation/manual/v3/overview/light.html.
func Light(path string) error {
cmd := exec.Command(
"docker", "run", "--rm", "--platform", "linux/386",
"--volume", path+":/wix", // mount volume
"dactiv/wix:latest", // image name
"light", "heat.wixobj", "main.wixobj", // command in image
"-ext", "WixUtilExtension",
"-b", "root", // Set directory for finding heat files
"-out", "orbit.msi",
"-sval", // skip validation (otherwise Wine crashes)
)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if err := cmd.Run(); err != nil {
return errors.Wrap(err, "light failed")
}
return nil
}