Comments (10)
TUF handles the hashing, signature verification, and download parts. Here's what the API currrently looks like (slightly simplified for explanatory purposes):
type Client interface {
// Update checks for updates and returns any added/changed targets.
Update() (Files, error)
// Targets returns a list of all available files.
Targets() Files
// Download downloads a named target into dest. The destination must
// not be used until the download is complete.
Download(string, io.Writer) error
}
type Files map[string]FileMeta
type FileMeta struct {
Length int64
Custom json.RawMessage
}
The Client
is initialized with the root key(s) and remote store to download from (typically an HTTP downloader with a base URL).
Note that the details of the hash/signature verification are completely hidden from the user, as they are easy to screw up (there is quite a bit going on behind the scenes).
With that in mind, I'd suggest dropping the Checksum
, Signature
, Verifier
, and Hash
fields, as well as the VerifyWithPEM
method, as they are all too low-level to be used safely. After doing this, the update flow looks like:
- Initialize TUF client, and call
Update
. - Figure out what target (if any) we want (perhaps go-update can help here).
- Create a temporary file and
Download
into it. - Tell go-update to perform the update using the temporary file.
from go-update.
Okay, sounds like I'll need to read TUF and understand all the attack vectors before continuing here. I'm reticent to remove those fields and functionality because I want go-update to support those operations (as safely as possible) so that it's a good primitive to work with even if you're not using TUF.
It should obviously be flexible enough to turn those things off if you're handling them at a higher level (like in TUF).
from go-update.
Here's the list of attack scenarios: https://github.com/theupdateframework/tuf/blob/v0.9.9/docs/tuf-spec.txt#L121-L155 (though the whole spec is worth a read)
from go-update.
Awesome, thanks! Definitely reading the whole spec.
from go-update.
I agree with @titanous in that the Update
struct feels a bit field-heavy. Instead of removing fields, though, I'd rather have optional fields with sane defaults. For example, if TargetMode
is not set, go-update should default to reusing the existing mode bits. (Admittedly, this breaks for "new" update files -- maybe require explicit mode bits in that case?)
I would also remove the Verifier
and Hash
fields and instead make them arguments to the Verify
functions. And having a Do()
function makes me a bit sad. Maybe I'm misreading this, but it seems like the Update
struct is meant to be reused? In that case, your design decisions make more sense, but personally I don't envision myself reusing an Update
.
go-update should make no assumptions about the implementation details of the patching, checksumming, or signature verification pieces. All of these must be pluggable.
I think this is the right approach, though I'm wary of how it might impact ease-of-use. The log
package is a good example of how you can provide both low-level controls and friendly defaults.
from go-update.
The Update
structure is intended to be used once and not reused. I was modeling the design after something like http.Client
: http://golang.org/pkg/net/http/#Client and http.Server
: http://golang.org/pkg/net/http/#Server
The docs will help make it clear that every field is optional and has a sane default except the Update
io.Reader. The minimal use of the package would look something like this:
func updateTo(newbytes []byte) {
up := update.Update{Update: bytes.NewReader(newbytes)}
err, errRecover := up.Do()
}
Perhaps a better design would be to make the single required parameter part of the call to Do
and leave the rest of the fields on the structure as optional:
func updateTo(newbytes []byte) {
err, errRecover := new(update.Update).Do(bytes.NewReader(newbytes))
}
Another possibility would be to design it as a top-level package function Do
or maybe Update
and rename the existing structure into Options
or Config
.
func updateTo(newbytes []byte) {
err, errRecover := update.Update(bytes.NewReader(newbytes), update.Options{
// all optional fields go here
TargetPath: "/path/to/file",
})
}
I'm not sure I understand what you mean about the changes to Verify
from go-update.
Good to see we're mostly on the same page. As for Verify
, I just meant that updates would look like:
up := Update{
TargetPath: "/path/to/target_file"
}
if err := up.VerifyChecksum(checksum, crypto.SHA256); err != nil {
return err
}
instead of:
up := Update{
TargetPath: "/path/to/target_file",
Checksum: checksum,
Hash: crypto.SHA256,
}
if err := up.VerifyChecksum(); err != nil {
return err
}
Now that I rethink it though, I'm not so sure which is better. Managing all these optional fields is tricky. The current method of chaining functions feels pretty clean, in part because you can almost read the call chain like an sentence: "update (and) VerifyChecksum FromUrl." However, specifying everything beforehand simplifies error handling, because you only have to check the errors returned by update.Do
(or update.Update
, or maybe update.Execute
or update.Apply
).
from go-update.
I like update.Apply
quite a bit.
from go-update.
We're rolling out our TUF-based updater with go-update for the Flynn CLI, the implementation might be useful for reference: https://github.com/flynn/flynn/blob/5fd0d5fac00f1baec4124e602b88a3e030e8fe49/cli/update.go#L73-L140
from go-update.
merged to master, closing
from go-update.
Related Issues (20)
- Attack possible by downgrading to earlier exploitable binary version by MITM HOT 5
- Quick Start Documentation HOT 1
- Tag release HOT 2
- can i get complete example program to understand self update usage? HOT 3
- Are you providing support for linux too? HOT 1
- Release osext as an independent package HOT 1
- Bug in Example? HOT 2
- Make switch of files more robust
- x HOT 1
- Wrong permissions HOT 1
- McAfee virus scanner cleans the new exe after update HOT 1
- example handler HOT 1
- Restart process after update HOT 3
- progress prompt
- Check directory permissions and throw an informative error when they are wrong
- Will this work inside a Macos dmg application? HOT 1
- Support go modules
- THIS PROJECT APPEARS TO BE UNMAINTAINED (details inside) HOT 2
- Equinox is shutting down on September 30th, 2021 HOT 1
- Self-update in parallel processes does not work properly
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go-update.