updater

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2024 License: BSD-3-Clause Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CLIENT_WYC                            = "client.wyc"
	IUCLIENT_IUC                          = "iuclient.iuc"    // inside client.wyc
	UPDTDETAILS_UDT                       = "updtdetails.udt" // inside .wyu archive
	INSTALL_FAILED_SENTINAL_WYS_FILE_NAME = "failed_install.wys"
)

Default file names

View Source
const (
	IUC_HEADER         = "IUCDFV2"
	WYS_HEADER         = "IUSDFV2"
	UPDTDETAILS_HEADER = "IUUDFV2"
)

File headers

View Source
const (
	EXIT_SUCCESS          = 0
	EXIT_NO_UPDATE        = 0
	EXIT_ERROR            = 1
	EXIT_UPDATE_AVALIABLE = 2
)

Exit codes

View Source
const (
	TLV_BOOL = iota
	TLV_BYTE
	TLV_DSTRING
	TLV_INT
	TLV_LONG
	TLV_STRING
)

wyUpdate value types

View Source
const (
	INT_UDT_NUMBER_OF_REGISTRY_CHANGES           = 0x20
	INT_UDT_NUMBER_OF_FILE_INFOS                 = 0x21 // (precedes file info list)
	UDT_BEGINNING_OF_FILE_INFORMATION_IDENTIFIER = 0x8B
	UDT_RELATIVE_FILE_PATH_DSTRING               = 0x40
	UDT_DELTA_PATCH_RELATIVE_PATH_DSTRING        = 0x47
	UDT_NEW_FILES_ADLER32_CHECKSUM_LONG          = 0x48
	UDT_END_OF_FILE_INFO_IDENTIFIER              = 0x9B
	STRING_UDT_SERVICE_TO_STOP_BEFORE_UPDATE     = 0x32
	STRING_UDT_SERVICE_TO_START_AFTER_UPDATE     = 0x33
	END_UDT                                      = 0xFF
)

UDT tags

View Source
const (
	A_LESS_THAN_B    = -1
	A_EQUAL_TO_B     = 0
	A_GREATER_THAN_B = 1
)
View Source
const (
	DSTRING_IUC_COMPANY_NAME           = 0x01
	DSTRING_IUC_PRODUCT_NAME           = 0x02
	DSTRING_IUC_INSTALLED_VERSION      = 0x03
	STRING_IUC_GUID                    = 0x0A
	DSTRING_IUC_SERVER_FILE_SITE       = 0x04
	DSTRING_IUC_WYUPDATE_SERVER_SITE   = 0x09
	DSTRING_IUC_HEADER_IMAGE_ALIGNMENT = 0x11
	INT_IUC_HEADER_TEXT_INDENT         = 0x12
	DSTRING_IUC_HEADER_TEXT_COLOR      = 0x13
	DSTRING_IUC_HEADER_FILENAME        = 0x14
	DSTRING_IUC_SIDE_IMAGE_FILENAME    = 0x15
	DSTRING_IUC_LANGUAGE_CULTURE       = 0x18 // e.g., en-US
	DSTRING_IUC_LANGUAGE_FILENAME      = 0x16
	BOOL_IUC_HIDE_HEADER_DIVIDER       = 0x17
	BOOL_IUC_CLOSE_WYUPDATE            = 0x19
	STRING_IUC_CUSTOM_TITLE_BAR        = 0x1A
	STRING_IUC_PUBLIC_KEY              = 0x1B
	END_IUC                            = 0xFF
)
View Source
const (
	DSTRING_WYS_CURRENT_LAST_VERSION      = 0x01
	DSTRING_WYS_SERVER_FILE_SITE          = 0x02
	DSTRING_WYS_MIN_CLIENT_VERSION        = 0x07
	INT_WYS_DUMMY_VAR_LEN                 = 0x0F
	DSTRING_WYS_VERSION_TO_UPDATE         = 0x0B
	DSTRING_WYS_UPDATE_FILE_SITE          = 0x03
	BYTE_WYS_RTF                          = 0x80
	DSTRING_WYS_LATEST_CHANGES            = 0x04
	LONG_WYS_UPDATE_FILE_SIZE             = 0x09
	LONG_WYS_UPDATE_FILE_ADLER32_CHECKSUM = 0x08
	BYTE_WYS_FILE_SHA1                    = 0x14
	INT_WYS_FOLDER                        = 0x0A
	DSTRING_WYS_UPDATE_ERROR_TEXT         = 0x20
	DSTRING_WYS_UPDATE_ERROR_LINK         = 0x21
	END_WYS                               = 0xFF
)

WYS tags

Variables

View Source
var (
	TimeoutDial         = time.Minute
	TimeoutTLSHandshake = time.Minute
	TimeoutClient       = 15 * time.Minute
)
View Source
var DelayDownload = time.Minute
View Source
var FallbackWYSURLs = []string{
	"https://huntress.io/updates/wyserver.wys?auth=%urlargs%",
}
View Source
var IUCTags = map[uint8]string{
	BOOL_IUC_CLOSE_WYUPDATE:            "BOOL_IUC_CLOSE_WYUPDATE",
	BOOL_IUC_HIDE_HEADER_DIVIDER:       "BOOL_IUC_HIDE_HEADER_DIVIDER",
	DSTRING_IUC_COMPANY_NAME:           "DSTRING_IUC_COMPANY_NAME",
	DSTRING_IUC_HEADER_FILENAME:        "DSTRING_IUC_HEADER_FILENAME",
	DSTRING_IUC_HEADER_IMAGE_ALIGNMENT: "DSTRING_IUC_HEADER_IMAGE_ALIGNMENT",
	DSTRING_IUC_HEADER_TEXT_COLOR:      "DSTRING_IUC_HEADER_TEXT_COLOR",
	DSTRING_IUC_INSTALLED_VERSION:      "DSTRING_IUC_INSTALLED_VERSION",
	DSTRING_IUC_LANGUAGE_CULTURE:       "DSTRING_IUC_LANGUAGE_CULTURE",
	DSTRING_IUC_LANGUAGE_FILENAME:      "DSTRING_IUC_LANGUAGE_FILENAME",
	DSTRING_IUC_PRODUCT_NAME:           "DSTRING_IUC_PRODUCT_NAME",
	DSTRING_IUC_SERVER_FILE_SITE:       "DSTRING_IUC_SERVER_FILE_SITE",
	DSTRING_IUC_SIDE_IMAGE_FILENAME:    "DSTRING_IUC_SIDE_IMAGE_FILENAME",
	DSTRING_IUC_WYUPDATE_SERVER_SITE:   "DSTRING_IUC_WYUPDATE_SERVER_SITE",
	INT_IUC_HEADER_TEXT_INDENT:         "INT_IUC_HEADER_TEXT_INDENT",
	STRING_IUC_CUSTOM_TITLE_BAR:        "STRING_IUC_CUSTOM_TITLE_BAR",
	STRING_IUC_GUID:                    "STRING_IUC_GUID",
	STRING_IUC_PUBLIC_KEY:              "STRING_IUC_PUBLIC_KEY",
	END_IUC:                            "END_IUC",
}
View Source
var UDTTags = map[uint8]string{
	INT_UDT_NUMBER_OF_REGISTRY_CHANGES:           "INT_UDT_NUMBER_OF_REGISTRY_CHANGES",
	INT_UDT_NUMBER_OF_FILE_INFOS:                 "INT_UDT_NUMBER_OF_FILE_INFOS",
	UDT_BEGINNING_OF_FILE_INFORMATION_IDENTIFIER: "UDT_BEGINNING_OF_FILE_INFORMATION_IDENTIFIER",
	UDT_RELATIVE_FILE_PATH_DSTRING:               "UDT_RELATIVE_FILE_PATH_DSTRING",
	UDT_DELTA_PATCH_RELATIVE_PATH_DSTRING:        "UDT_DELTA_PATCH_RELATIVE_PATH_DSTRING",
	UDT_NEW_FILES_ADLER32_CHECKSUM_LONG:          "UDT_NEW_FILES_ADLER32_CHECKSUM_LONG",
	UDT_END_OF_FILE_INFO_IDENTIFIER:              "UDT_END_OF_FILE_INFO_IDENTIFIER",
	STRING_UDT_SERVICE_TO_STOP_BEFORE_UPDATE:     "STRING_UDT_SERVICE_TO_STOP_BEFORE_UPDATE",
	STRING_UDT_SERVICE_TO_START_AFTER_UPDATE:     "STRING_UDT_SERVICE_TO_START_AFTER_UPDATE",
	END_UDT:                                      "END_UDT",
}

UDT tag to string mapping

View Source
var WYSTags = map[uint8]string{
	BYTE_WYS_FILE_SHA1:                    "BYTE_WYS_FILE_SHA1",
	BYTE_WYS_RTF:                          "BYTE_WYS_RTF",
	DSTRING_WYS_CURRENT_LAST_VERSION:      "DSTRING_WYS_CURRENT_LAST_VERSION",
	DSTRING_WYS_LATEST_CHANGES:            "DSTRING_WYS_LATEST_CHANGES",
	DSTRING_WYS_MIN_CLIENT_VERSION:        "DSTRING_WYS_MIN_CLIENT_VERSION",
	DSTRING_WYS_SERVER_FILE_SITE:          "DSTRING_WYS_SERVER_FILE_SITE",
	DSTRING_WYS_UPDATE_ERROR_LINK:         "DSTRING_WYS_UPDATE_ERROR_LINK",
	DSTRING_WYS_UPDATE_ERROR_TEXT:         "DSTRING_WYS_UPDATE_ERROR_TEXT",
	DSTRING_WYS_UPDATE_FILE_SITE:          "DSTRING_WYS_UPDATE_FILE_SITE",
	DSTRING_WYS_VERSION_TO_UPDATE:         "DSTRING_WYS_VERSION_TO_UPDATE",
	END_WYS:                               "END_WYS",
	INT_WYS_DUMMY_VAR_LEN:                 "INT_WYS_DUMMY_VAR_LEN",
	INT_WYS_FOLDER:                        "INT_WYS_FOLDER",
	LONG_WYS_UPDATE_FILE_ADLER32_CHECKSUM: "LONG_WYS_UPDATE_FILE_ADLER32_CHECKSUM",
	LONG_WYS_UPDATE_FILE_SIZE:             "LONG_WYS_UPDATE_FILE_SIZE",
}

WYSTags is a mapping of WYS tags to strings

Functions

func AddFileToWYCArchive

func AddFileToWYCArchive(zipWriter *zip.Writer, filename string) error

AddFileToWYCArchive adds a file to the archive

func BackupFiles

func BackupFiles(updates []string, srcDir string) (backupDir string, err error)

BackupFiles copies all the files to be updated in `srcDir` to a `backupDir` `backupDir` is returned

func CheckForUpdateHandler

func CheckForUpdateHandler(infoer Info, args Args) (int, error)

CheckForUpdateHandler checks to see if an update is availible. Returns int exit code and error.

func CompareVersions

func CompareVersions(a string, b string) int

CompareVersions compares two versions and returns an integer that indicates their relationship in the sort order. Return a negative number if versionA is less than versionB, 0 if they're equal, a positive number if versionA is greater than versionB.

func CreateTempDir

func CreateTempDir() (tempDir string, err error)

CreateTempDir returns a temporary directory name and error if the creation failed

func CreateWYCArchive

func CreateWYCArchive(filename string, files []string) error

CreateWYCArchive compresses files into a .wyc archive

func DeleteDirectory

func DeleteDirectory(dir string)

func DownloadFileToDisk

func DownloadFileToDisk(urls []string, localpath string) error

DownloadFileToDisk will download the content linked by one of the provided urls and save it locally to localpath. It will try all URLs in order until one succeeds. If all fail it will return an error.

func DownloadFileToWriter

func DownloadFileToWriter(urls []string, writer io.Writer) error

DownloadFileToWriter will download the content linked by one of the provided urls and write it to the provided writer. It will try all URLs in order until one succeeds. If all fail it will return an error.

func GenerateSHA1HashFromFilePath

func GenerateSHA1HashFromFilePath(filePath string) (hash []byte, err error)

GenerateSHA1HashFromFilePath returns the SHA1 hash of the contents for the filePath. hash will always be zero value when err is not nil.

func GenerateSHA1HashFromReader

func GenerateSHA1HashFromReader(reader io.Reader) (hash []byte, err error)

GenerateSHA1HashFromReader returns the SHA1 hash of the contents read from the reader. hash will always be zero value when err is not nil.

func GetAdler32

func GetAdler32(file string) (uint32, error)

GetAdler32 returns the Adler32 checksum of a file

func GetExeDir

func GetExeDir() string

GetExeDir returns the directory name of the executable

func GetFallbackWYSURLs added in v1.0.2

func GetFallbackWYSURLs(args Args) []string

GetFallbackWYSURLs returns a list of fallback URLs when the local WYC file is missing or invalid.

func HTTPGetFile

func HTTPGetFile(url string, writer io.Writer) error

HTTPGetFile GETs the contented linked by the URL and writes it to the writer and returns an error if the content is HTML or the HTTP request doesn't respond with 200 (OK).

func Handler

func Handler() int

Handler is the "main" called by cmd/main.go

func InstallUpdate

func InstallUpdate(udt ConfigUDT, srcFiles []string, installDir string) error

InstallUpdate start/stops service and moves the new files into the `installDir`

func LogErrorMsg

func LogErrorMsg(args Args, msg string)

LogErrorMsg will write to a log file if a log file was specified

func LogOutputInfoMsg

func LogOutputInfoMsg(args Args, msg string)

LogOutputInfoMsg will write a msg to STDOUT or a log file if one was specified

func MoveFile

func MoveFile(file string, dst string) error

MoveFile moves a `file` to `dst`

func MoveFileIgnoreMissing

func MoveFileIgnoreMissing(src string, dst string) error

MoveFileIgnoreMissing will not return an error if `src` does not exist

func PruneTempDirs added in v1.0.2

func PruneTempDirs(threshold time.Duration, limit int) (deleted int, err error)

PruneTempDirs deletes temporary directories in GetExeDir matching the TempDirPrefix that have not been modified within the specified threshold. If a limit is specified, no more than the specified number of temporary directories will be deleted.

func RollbackFiles

func RollbackFiles(backupDir string, dstDir string) (err error)

RollbackFiles copies all the files from `backupDir` to `dstDir`

func TempDirPrefix

func TempDirPrefix() string

func Unzip

func Unzip(srcArchive string, destDir string) (root string, filenames []string, err error)

Unzip will decompress a zip archive, moving all compressed files/folders to the specified output directory.

func UpdateHandler

func UpdateHandler(infoer Infoer, args Args) (int, error)

UpdateHandler performs the update. Returns int exit code and error.

func ValueToBool

func ValueToBool(tlv *TLV) bool

ValueToBool reads the TLV Value field as a boolean

func ValueToByteSlice

func ValueToByteSlice(tlv *TLV) []byte

ValueToByteSlice just return the TLV Value field (byte slice)

func ValueToInt

func ValueToInt(tlv *TLV) int

ValueToInt reads the TLV Value field as an integer

func ValueToLong

func ValueToLong(tlv *TLV) int64

ValueToLong reads the TLV Value field as an int64 (long)

func ValueToString

func ValueToString(tlv *TLV) string

ValueToString interprets the TLV Value field as a string and returns it

func VerifyAdler32Checksum

func VerifyAdler32Checksum(expected int64, file string) bool

VerifyAdler32Checksum returns true if checksum was verified

func VerifyHash

func VerifyHash(pub *rsa.PublicKey, hashed []byte, sig []byte) error

VerifyHash verifies the signed SHA1

func WriteUDT

func WriteUDT(udt ConfigUDT, path string) error

WriteUDT writes a UDT file Not all wyUpdate UDT options are implemented This is currently only used in testing

Types

type Args

type Args struct {
	Debug         bool
	Quickcheck    bool
	Justcheck     bool
	Noerr         bool
	Fromservice   bool
	Urlargs       string
	Outputinfo    bool
	OutputinfoLog string
	Logfile       string
	Cdata         string
	WYSTestServer string // Used for testing
	WYUTestServer string // Used for testing
}

Args contains the parsed command-line arguments

func ParseArgs

func ParseArgs(argsSlice []string) (args Args, err error)

ParseArgs returns a struct with the parsed command-line arguments

type CandidateUpdateRequest

type CandidateUpdateRequest struct {
	ConfigIUC               ConfigIUC
	CandidateWysFileContent bytes.Buffer
	ConfigWYS               ConfigWYS
}

CandidateUpdateRequest represents all the data necessary to define and generate a request for an [agent] update

func NewCandidateUpdateRequest

func NewCandidateUpdateRequest(args Args, wyFileParser Infoer) (req CandidateUpdateRequest, err error)

NewCandidateUpdateRequest returns a populated req if all the prerequisites to generate one are present. req will always be zero value when err is not nil.

type ConfigIUC

type ConfigIUC struct {
	IucCompanyName          TLV
	IucProductName          TLV
	IucInstalledVersion     TLV
	IucGUID                 TLV
	IucServerFileSite       []TLV
	IucWyupdateServerSite   []TLV
	IucHeaderImageAlignment TLV
	IucHeaderTextIndent     TLV
	IucHeaderTextColor      TLV
	IucHeaderFilename       TLV
	IucSideImageFilename    TLV
	IucLanguageCulture      TLV
	IucLanguageFilename     TLV
	IucHideHeaderDivider    TLV
	IucCloseWyupate         TLV
	IucCustomTitleBar       TLV
	IucPublicKey            TLV
}

func (ConfigIUC) GetWYSURLs

func (config ConfigIUC) GetWYSURLs(args Args) (urls []string)

GetWYSURLs returns the ServerFileSite(s) listed in the WYC file associated with config and populates urls with the site URLs. args are used to inject any CLI provided URL arguments and allow for overriding of the site URL.

type ConfigUDT

type ConfigUDT struct {
	ServiceToStopBeforeUpdate []TLV
	ServiceToStartAfterUpdate []TLV
	NumberOfFileInfos         TLV
	NumberOfRegistryChanges   TLV
}

func GetUpdateDetails

func GetUpdateDetails(extractedFiles []string) (udt ConfigUDT, updates []string, err error)

GetUpdateDetails finds the updtdetails.udt in a list of files extracted from a wyu archive. It returns a `ConfigUDT` and a list of the files to update.

func ParseUDT

func ParseUDT(path string) (ConfigUDT, error)

ParseUDT parses a updtdetails.udt file

type ConfigWYS

type ConfigWYS struct {
	FileSha1           []byte
	RTF                []byte
	CurrentLastVersion string
	LatestChanges      string
	MinClientVersion   string
	ServerFileSite     string
	UpdateErrorLink    string
	UpdateErrorText    string
	UpdateFileSite     []string // hosts the WYU file
	VersionToUpdate    string
	DummyVarLen        int
	WYSFolder          int
	UpdateFileAdler32  int64
	UpdateFileSize     int64
}

ConfigWYS contains the server file (WYS) details

func (ConfigWYS) GetWYUURLs

func (wys ConfigWYS) GetWYUURLs(args Args) (urls []string)

GetWYUURLs returns the UpdateFileSite(s) included in the WYS file associated with config and populates urls with the site URLs. args are used to inject any CLI provided URL arguments and allow for overriding of the site URL.

type Info

type Info struct{}

Info struct for the Infoer interface

func (Info) ParseWYC

func (wycInfo Info) ParseWYC(compressedWYC string) (ConfigIUC, error)

ParseWYC parses a compress WYC file, returning the details as a ConfigIUC struct

func (Info) ParseWYSFromFilePath

func (wysInfo Info) ParseWYSFromFilePath(compressedWYSFilePath string, _ Args) (wys ConfigWYS, err error)

ParseWYSFromReader returns the parsed contents, wys, as read from the compressedWYSFilePath. wys will always be zero value when err is not nil.

func (Info) ParseWYSFromReader

func (wysInfo Info) ParseWYSFromReader(reader io.ReaderAt, size int64) (wys ConfigWYS, err error)

ParseWYSFromReader returns the parsed contents, wys, as read from the reader, which are assumed to be a compresseed WYS file, annotated with the content size. wys will always be zero value when err is not nil.

type Infoer

type Infoer interface {
	ParseWYSFromReader(reader io.ReaderAt, size int64) (wys ConfigWYS, err error)
	ParseWYSFromFilePath(compressedWYSFilePath string, _ Args) (wys ConfigWYS, err error)
	ParseWYC(string) (ConfigIUC, error)
}

Infoer interface used to make testing easier

type Key

type Key struct {
	ModulusString  string        `xml:"Modulus"`
	ExponentString string        `xml:"Exponent"`
	Modulus        *big.Int      `xml:"-"`
	Exponent       int           `xml:"-"`
	PublicKey      rsa.PublicKey `xml:"-"`
}

Key stores the public key information (modulus and exponent)

func ParsePublicKey

func ParsePublicKey(s string) (Key, error)

ParsePublicKey parses a string in the form of <RSAKeyValue><Modulus>%s</Modulus><Exponent>%s</Exponent></RSAKeyValue> returning a struct

type TLV

type TLV struct {
	Tag        uint8  // wyUpdate tag
	TagString  string // to help debug
	Type       int    // wyUpdate value type
	DataLength uint32 // used in wyUpdate d. strings
	Length     uint32
	Value      []byte
}

TLV type, length, value (and some helpers)

func ReadUDTTLV

func ReadUDTTLV(r io.Reader) (*TLV, error)

ReadUDTTLV reads a single TLV and returns it

func ReadWYSTLV

func ReadWYSTLV(r io.Reader) *TLV

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL