omaha

package
v0.0.0-...-3c546fa Latest Latest
Warning

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

Go to latest
Published: Sep 24, 2020 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Google's Omaha application update protocol, version 3.

Omaha is a poll based protocol using XML. Requests are made by clients to check for updates or report events of an update process. Responses are given by the server to provide update information, if any, or to simply acknowledge the receipt of event status.

https://github.com/google/omaha/blob/master/doc/ServerProtocolV3.md

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	PackageHashMismatchError = errors.New("package hash is invalid")
	PackageSizeMismatchError = errors.New("package size is invalid")
)

Functions

func LocalArch

func LocalArch() string

Translate GOARCH to Omaha's choice of names, because no two independent software projects *ever* use the same set of architecture names. ;-)

func LocalPlatform

func LocalPlatform() string

Translate GOOS to Omaha's platform names as best as we can.

Types

type Action

type Action struct {
	Event string `xml:"event,attr"`

	// update engine extensions for event="postinstall"
	DisplayVersion        string `xml:"DisplayVersion,attr,omitempty"`
	SHA256                string `xml:"sha256,attr,omitempty"`
	NeedsAdmin            bool   `xml:"needsadmin,attr,omitempty"`
	IsDeltaPayload        bool   `xml:"IsDeltaPayload,attr,omitempty"`
	DisablePayloadBackoff bool   `xml:"DisablePayloadBackoff,attr,omitempty"`
	MaxFailureCountPerURL uint   `xml:"MaxFailureCountPerUrl,attr,omitempty"`
	MetadataSignatureRsa  string `xml:"MetadataSignatureRsa,attr,omitempty"`
	MetadataSize          string `xml:"MetadataSize,attr,omitempty"`
	Deadline              string `xml:"deadline,attr,omitempty"`
	MoreInfo              string `xml:"MoreInfo,attr,omitempty"`
	Prompt                bool   `xml:"Prompt,attr,omitempty"`
}

type AppRequest

type AppRequest struct {
	Ping        *PingRequest    `xml:"ping"`
	UpdateCheck *UpdateRequest  `xml:"updatecheck"`
	Events      []*EventRequest `xml:"event" json:",omitempty"`
	ID          string          `xml:"appid,attr,omitempty"`
	Client      string          `xml:"client,attr,omitempty"`
	InstallAge  string          `xml:"installage,attr,omitempty"`
	Lang        string          `xml:"lang,attr,omitempty"`
	NextVersion string          `xml:"nextversion,attr,omitempty"`
	Version     string          `xml:"version,attr,omitempty"`

	// update engine extensions
	Board     string `xml:"board,attr,omitempty"`
	DeltaOK   bool   `xml:"delta_okay,attr,omitempty"`
	FromTrack string `xml:"from_track,attr,omitempty"`
	Track     string `xml:"track,attr,omitempty"`

	// coreos update engine extensions
	AlephVersion string `xml:"alephversion,attr,omitempty"`
	BootID       string `xml:"bootid,attr,omitempty"`
	MachineID    string `xml:"machineid,attr,omitempty"`
	OEM          string `xml:"oem,attr,omitempty"`
	OEMVersion   string `xml:"oemversion,attr,omitempty"`
}

func (*AppRequest) AddEvent

func (a *AppRequest) AddEvent() *EventRequest

func (*AppRequest) AddPing

func (a *AppRequest) AddPing() *PingRequest

func (*AppRequest) AddUpdateCheck

func (a *AppRequest) AddUpdateCheck() *UpdateRequest

type AppResponse

type AppResponse struct {
	Ping        *PingResponse    `xml:"ping"`
	UpdateCheck *UpdateResponse  `xml:"updatecheck"`
	Events      []*EventResponse `xml:"event" json:",omitempty"`
	ID          string           `xml:"appid,attr,omitempty"`
	Status      AppStatus        `xml:"status,attr,omitempty"`
}

func (*AppResponse) AddEvent

func (a *AppResponse) AddEvent() *EventResponse

func (*AppResponse) AddPing

func (a *AppResponse) AddPing() *PingResponse

func (*AppResponse) AddUpdateCheck

func (a *AppResponse) AddUpdateCheck(status UpdateStatus) *UpdateResponse

type AppStatus

type AppStatus string
const (
	// Standard values
	AppOK         AppStatus = "ok"
	AppRestricted AppStatus = "restricted"
	AppUnknownID  AppStatus = "error-unknownApplication"
	AppInvalidID  AppStatus = "error-invalidAppId"

	// Extra error values
	AppInvalidVersion AppStatus = "error-invalidVersion"
	AppInternalError  AppStatus = "error-internal"
)

func (AppStatus) Error

func (a AppStatus) Error() string

Make AppStatus easy to use as an error

type DayStart

type DayStart struct {
	ElapsedSeconds string `xml:"elapsed_seconds,attr"`
}

type EventRequest

type EventRequest struct {
	Type            EventType   `xml:"eventtype,attr"`
	Result          EventResult `xml:"eventresult,attr"`
	ErrorCode       int         `xml:"errorcode,attr,omitempty"`
	NextVersion     string      `xml:"nextversion,attr,omitempty"`
	PreviousVersion string      `xml:"previousversion,attr,omitempty"`
}

type EventResponse

type EventResponse struct {
	Status string `xml:"status,attr"` // Always "ok".
}

type EventResult

type EventResult int
const (
	EventResultError                 EventResult = 0
	EventResultSuccess               EventResult = 1
	EventResultSuccessReboot         EventResult = 2
	EventResultSuccessRestartBrowser EventResult = 3
	EventResultCancelled             EventResult = 4
	EventResultErrorInstallerMSI     EventResult = 5
	EventResultErrorInstallerOther   EventResult = 6
	EventResultNoUpdate              EventResult = 7
	EventResultInstallerSystem       EventResult = 8
	EventResultUpdateDeferred        EventResult = 9
	EventResultHandoffError          EventResult = 10
)

func (EventResult) String

func (e EventResult) String() string

type EventType

type EventType int
const (
	EventTypeUnknown                      EventType = 0
	EventTypeDownloadComplete             EventType = 1
	EventTypeInstallComplete              EventType = 2
	EventTypeUpdateComplete               EventType = 3
	EventTypeUninstall                    EventType = 4
	EventTypeDownloadStarted              EventType = 5
	EventTypeInstallStarted               EventType = 6
	EventTypeNewApplicationInstallStarted EventType = 9
	EventTypeSetupStarted                 EventType = 10
	EventTypeSetupFinished                EventType = 11
	EventTypeUpdateApplicationStarted     EventType = 12
	EventTypeUpdateDownloadStarted        EventType = 13
	EventTypeUpdateDownloadFinished       EventType = 14
	EventTypeUpdateInstallerStarted       EventType = 15
	EventTypeSetupUpdateBegin             EventType = 16
	EventTypeSetupUpdateComplete          EventType = 17
	EventTypeRegisterProductComplete      EventType = 20
	EventTypeOEMInstallFirstCheck         EventType = 30
	EventTypeAppSpecificCommandStarted    EventType = 40
	EventTypeAppSpecificCommandEnded      EventType = 41
	EventTypeSetupFailure                 EventType = 100
	EventTypeComServerFailure             EventType = 102
	EventTypeSetupUpdateFailure           EventType = 103
)

func (EventType) String

func (e EventType) String() string

type Manifest

type Manifest struct {
	Packages []*Package `xml:"packages>package"`
	Actions  []*Action  `xml:"actions>action"`
	Version  string     `xml:"version,attr"`
}

func (*Manifest) AddAction

func (m *Manifest) AddAction(event string) *Action

func (*Manifest) AddPackage

func (m *Manifest) AddPackage() *Package

func (*Manifest) AddPackageFromPath

func (m *Manifest) AddPackageFromPath(path string) (*Package, error)

type OS

type OS struct {
	Platform    string `xml:"platform,attr,omitempty"`
	Version     string `xml:"version,attr,omitempty"`
	ServicePack string `xml:"sp,attr,omitempty"`
	Arch        string `xml:"arch,attr,omitempty"`
}

type OmahaHandler

type OmahaHandler struct {
	Updater
}

func (*OmahaHandler) ServeHTTP

func (o *OmahaHandler) ServeHTTP(w http.ResponseWriter, httpReq *http.Request)

type Package

type Package struct {
	Name     string `xml:"name,attr"`
	SHA1     string `xml:"hash,attr"`
	SHA256   string `xml:"hash_sha256,attr,omitempty"`
	Size     uint64 `xml:"size,attr"`
	Required bool   `xml:"required,attr"`
}

Package represents a single downloadable file.

func (*Package) FromPath

func (p *Package) FromPath(name string) error

func (*Package) FromReader

func (p *Package) FromReader(r io.Reader) error

func (*Package) Verify

func (p *Package) Verify(dir string) error

func (*Package) VerifyReader

func (p *Package) VerifyReader(r io.Reader) error

type PingRequest

type PingRequest struct {
	Active               int  `xml:"active,attr,omitempty"`
	LastActiveReportDays *int `xml:"a,attr,omitempty"`
	LastReportDays       int  `xml:"r,attr,omitempty"`
}

type PingResponse

type PingResponse struct {
	Status string `xml:"status,attr"` // Always "ok".
}

type Request

type Request struct {
	XMLName       xml.Name      `xml:"request" json:"-"`
	OS            *OS           `xml:"os"`
	Apps          []*AppRequest `xml:"app"`
	Protocol      string        `xml:"protocol,attr"`
	InstallSource string        `xml:"installsource,attr,omitempty"`
	IsMachine     int           `xml:"ismachine,attr,omitempty"`
	RequestID     string        `xml:"requestid,attr,omitempty"`
	SessionID     string        `xml:"sessionid,attr,omitempty"`
	TestSource    string        `xml:"testsource,attr,omitempty"`
	UserID        string        `xml:"userid,attr,omitempty"`
	Version       string        `xml:"version,attr,omitempty"`

	// update engine extension, duplicates the version attribute.
	UpdaterVersion string `xml:"updaterversion,attr,omitempty"`
}

Request sent by the Omaha client

func NewRequest

func NewRequest() *Request
Example
request := NewRequest()
request.Version = ""
request.OS = &OS{
	Platform:    "Chrome OS",
	Version:     "Indy",
	ServicePack: "ForcedUpdate_x86_64",
}
app := request.AddApp("{27BD862E-8AE8-4886-A055-F7F1A6460627}", "1.0.0.0")
app.AddUpdateCheck()

event := app.AddEvent()
event.Type = EventTypeDownloadComplete
event.Result = EventResultError

if raw, err := xml.MarshalIndent(request, "", " "); err != nil {
	fmt.Println(err)
	return
} else {
	fmt.Printf("%s%s\n", xml.Header, raw)
}
Output:

<?xml version="1.0" encoding="UTF-8"?>
<request protocol="3.0">
 <os platform="Chrome OS" version="Indy" sp="ForcedUpdate_x86_64"></os>
 <app appid="{27BD862E-8AE8-4886-A055-F7F1A6460627}" version="1.0.0.0">
  <updatecheck></updatecheck>
  <event eventtype="1" eventresult="0"></event>
 </app>
</request>

func ParseRequest

func ParseRequest(contentType string, body io.Reader) (*Request, error)

ParseRequest verifies and returns the parsed Request document. The MIME Content-Type header may be provided to sanity check its value; if blank it is assumed to be XML in UTF-8.

func (*Request) AddApp

func (r *Request) AddApp(id, version string) *AppRequest

func (*Request) GetApp

func (r *Request) GetApp(id string) *AppRequest

type Response

type Response struct {
	XMLName  xml.Name       `xml:"response" json:"-"`
	DayStart DayStart       `xml:"daystart"`
	Apps     []*AppResponse `xml:"app"`
	Protocol string         `xml:"protocol,attr"`
	Server   string         `xml:"server,attr"`
}

Response sent by the Omaha server

func NewResponse

func NewResponse() *Response
Example
response := NewResponse()
app := response.AddApp("{52F1B9BC-D31A-4D86-9276-CBC256AADF9A}", "ok")
app.AddPing()
u := app.AddUpdateCheck(UpdateOK)
u.AddURL("http://localhost/updates")
m := u.AddManifest("9999.0.0")
k := m.AddPackage()
k.SHA1 = "+LXvjiaPkeYDLHoNKlf9qbJwvnk="
k.Name = "update.gz"
k.Size = 67546213
k.Required = true
a := m.AddAction("postinstall")
a.DisplayVersion = "9999.0.0"
a.SHA256 = "0VAlQW3RE99SGtSB5R4m08antAHO8XDoBMKDyxQT/Mg="
a.NeedsAdmin = false
a.IsDeltaPayload = true
a.DisablePayloadBackoff = true

if raw, err := xml.MarshalIndent(response, "", " "); err != nil {
	fmt.Println(err)
	return
} else {
	fmt.Printf("%s%s\n", xml.Header, raw)
}
Output:

<?xml version="1.0" encoding="UTF-8"?>
<response protocol="3.0" server="go-omaha">
 <daystart elapsed_seconds="0"></daystart>
 <app appid="{52F1B9BC-D31A-4D86-9276-CBC256AADF9A}" status="ok">
  <ping status="ok"></ping>
  <updatecheck status="ok">
   <urls>
    <url codebase="http://localhost/updates"></url>
   </urls>
   <manifest version="9999.0.0">
    <packages>
     <package name="update.gz" hash="+LXvjiaPkeYDLHoNKlf9qbJwvnk=" size="67546213" required="true"></package>
    </packages>
    <actions>
     <action event="postinstall" DisplayVersion="9999.0.0" sha256="0VAlQW3RE99SGtSB5R4m08antAHO8XDoBMKDyxQT/Mg=" IsDeltaPayload="true" DisablePayloadBackoff="true"></action>
    </actions>
   </manifest>
  </updatecheck>
 </app>
</response>

func ParseResponse

func ParseResponse(contentType string, body io.Reader) (*Response, error)

ParseResponse verifies and returns the parsed Response document. The MIME Content-Type header may be provided to sanity check its value; if blank it is assumed to be XML in UTF-8.

func (*Response) AddApp

func (r *Response) AddApp(id string, status AppStatus) *AppResponse

func (*Response) GetApp

func (r *Response) GetApp(id string) *AppResponse

type Server

type Server struct {
	Updater

	Mux *http.ServeMux
	// contains filtered or unexported fields
}

func NewServer

func NewServer(addr string, updater Updater) (*Server, error)

func (*Server) Addr

func (s *Server) Addr() net.Addr

func (*Server) Destroy

func (s *Server) Destroy() error

func (*Server) Serve

func (s *Server) Serve() error

type TrivialServer

type TrivialServer struct {
	*Server
	// contains filtered or unexported fields
}

TrivialServer is an extremely basic Omaha server that ignores all incoming metadata, always responding with the same update response. The update is constructed by calling AddPackage one or more times.

func NewTrivialServer

func NewTrivialServer(addr string) (*TrivialServer, error)

func (*TrivialServer) AddPackage

func (ts *TrivialServer) AddPackage(file, name string) error

AddPackage adds a new file to the update response. file is the local filesystem path, name is the final URL component.

func (*TrivialServer) SetVersion

func (ts *TrivialServer) SetVersion(version string)

SetVersion sets the manifest's version with the provided one.

type URL

type URL struct {
	CodeBase string `xml:"codebase,attr"`
}

type Update

type Update struct {
	XMLName         xml.Name `xml:"update" json:"-"`
	ID              string   `xml:"appid,attr"`
	PreviousVersion string   `xml:"previousversion,attr,omitempty"`
	URL             URL      `xml:"urls>url"`
	Manifest

	// The delta_okay request attribute is an update_engine extension.
	RespectDeltaOK bool `xml:"respect_delta_okay,attr,omitempty"`
}

Update is a manifest for a single omaha update response. It extends the standard Manifest protocol element with the application id and previous version which are used to match against the update request. A blank previous version indicates this update can be applied to any existing install. The application id may not be blank.

func (*Update) URLs

func (u *Update) URLs(prefixes []string) []*URL

The URL attribute in Update is currently assumed to be a relative path which may be found on multiple mirrors. A server using this is expected to know the mirror prefix(s) it can give the client.

type UpdateRequest

type UpdateRequest struct {
	TargetVersionPrefix string `xml:"targetversionprefix,attr,omitempty"`
}

type UpdateResponse

type UpdateResponse struct {
	URLs     []*URL       `xml:"urls>url" json:",omitempty"`
	Manifest *Manifest    `xml:"manifest"`
	Status   UpdateStatus `xml:"status,attr,omitempty"`
}

func (*UpdateResponse) AddManifest

func (u *UpdateResponse) AddManifest(version string) *Manifest

func (*UpdateResponse) AddURL

func (u *UpdateResponse) AddURL(codebase string) *URL

type UpdateStatus

type UpdateStatus string
const (
	NoUpdate                   UpdateStatus = "noupdate"
	UpdateOK                   UpdateStatus = "ok"
	UpdateOSNotSupported       UpdateStatus = "error-osnotsupported"
	UpdateUnsupportedProtocol  UpdateStatus = "error-unsupportedProtocol"
	UpdatePluginRestrictedHost UpdateStatus = "error-pluginRestrictedHost"
	UpdateHashError            UpdateStatus = "error-hash"
	UpdateInternalError        UpdateStatus = "error-internal"
)

func (UpdateStatus) Error

func (u UpdateStatus) Error() string

Make UpdateStatus easy to use as an error

type Updater

type Updater interface {
	CheckApp(req *Request, app *AppRequest) error
	CheckUpdate(req *Request, app *AppRequest) (*Update, error)
	Event(req *Request, app *AppRequest, event *EventRequest)
	Ping(req *Request, app *AppRequest)
}

Updater provides a common interface for any backend that can respond to update requests made to an Omaha server.

type UpdaterStub

type UpdaterStub struct{}

func (UpdaterStub) CheckApp

func (u UpdaterStub) CheckApp(req *Request, app *AppRequest) error

func (UpdaterStub) CheckUpdate

func (u UpdaterStub) CheckUpdate(req *Request, app *AppRequest) (*Update, error)

func (UpdaterStub) Event

func (u UpdaterStub) Event(req *Request, app *AppRequest, event *EventRequest)

func (UpdaterStub) Ping

func (u UpdaterStub) Ping(req *Request, app *AppRequest)

Directories

Path Synopsis
Package client provides a general purpose Omaha update client implementation.
Package client provides a general purpose Omaha update client implementation.

Jump to

Keyboard shortcuts

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