From 3ad355aae291db5eac3230b8d7114bb101134431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Fri, 19 Jun 2015 18:02:44 +0200 Subject: [PATCH] Add hash checking and fix hexadecimal chardata --- cmd/fdroidcl/install.go | 2 +- cmd/fdroidcl/update.go | 37 +++++++++++++++++++++++++++---------- index.go | 27 +++++++++++++++++++++------ 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/cmd/fdroidcl/install.go b/cmd/fdroidcl/install.go index d21c0b5..6e9e22c 100644 --- a/cmd/fdroidcl/install.go +++ b/cmd/fdroidcl/install.go @@ -32,7 +32,7 @@ func runInstall(args []string) { apk := app.CurApk url := fmt.Sprintf("%s/%s", repoURL, apk.ApkName) path := filepath.Join(apksDir, apk.ApkName) - if err := downloadEtag(url, path); err != nil { + if err := downloadEtag(url, path, apk.Hash.Data); err != nil { log.Fatalf("Could not download '%s': %v", app.ID, err) } paths[i] = path diff --git a/cmd/fdroidcl/update.go b/cmd/fdroidcl/update.go index 4884d57..7fb410d 100644 --- a/cmd/fdroidcl/update.go +++ b/cmd/fdroidcl/update.go @@ -4,6 +4,9 @@ package main import ( + "bytes" + "crypto/sha256" + "errors" "fmt" "io" "io/ioutil" @@ -33,7 +36,7 @@ func runUpdate(args []string) { func updateIndex() error { url := fmt.Sprintf("%s/%s", repoURL, "index.jar") - if err := downloadEtag(url, indexPath(repoName)); err != nil { + if err := downloadEtag(url, indexPath(repoName), nil); err != nil { return err } return nil @@ -47,8 +50,9 @@ func respEtag(resp *http.Response) string { return etags[0] } -func downloadEtag(url, path string) error { +func downloadEtag(url, path string, sum []byte) error { fmt.Printf("Downloading %s...", url) + defer fmt.Println() client := &http.Client{} req, err := http.NewRequest("GET", url, nil) @@ -64,22 +68,35 @@ func downloadEtag(url, path string) error { } defer resp.Body.Close() if resp.StatusCode == http.StatusNotModified { - fmt.Println(" not modified") + fmt.Printf(" not modified") return nil } f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { return err } - _, err = io.Copy(f, resp.Body) - err2 := ioutil.WriteFile(etagPath, []byte(respEtag(resp)), 0644) - if err != nil { - return err + if sum == nil { + _, err := io.Copy(f, resp.Body) + if err != nil { + return err + } + } else { + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + got := sha256.Sum256(data) + if !bytes.Equal(sum, got[:]) { + return errors.New("sha256 mismatch") + } + if _, err := f.Write(data); err != nil { + return err + } } - if err2 != nil { - return err2 + if err := ioutil.WriteFile(etagPath, []byte(respEtag(resp)), 0644); err != nil { + return err } - fmt.Println(" done") + fmt.Printf(" done") return nil } diff --git a/index.go b/index.go index 20736c3..5944d60 100644 --- a/index.go +++ b/index.go @@ -39,14 +39,29 @@ func (cl *commaList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error type hexVal []byte -func (hv *hexVal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { +func (hv *hexVal) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) { var content string - var err error if err = d.DecodeElement(&content, &start); err != nil { - return err + return } *hv, err = hex.DecodeString(content) - return err + return +} + +func (hv *hexVal) UnmarshalText(text []byte) (err error) { + *hv, err = hex.DecodeString(string(text)) + return +} + +func (hv *hexVal) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + s := hex.EncodeToString(*hv) + e.EncodeElement(s, start) + return nil +} + +func (hv *hexVal) MarshalText() (result []byte, err error) { + s := hex.EncodeToString(*hv) + return []byte(s), nil } // App is an Android application @@ -72,7 +87,7 @@ type App struct { CurApk *Apk } -type Hash struct { +type HexHash struct { Type string `xml:"type,attr"` Data hexVal `xml:",chardata"` } @@ -105,7 +120,7 @@ type Apk struct { Added dateVal `xml:"added"` Perms commaList `xml:"permissions"` Feats commaList `xml:"features"` - Hashes []Hash `xml:"hash"` + Hash HexHash `xml:"hash"` } func (app *App) calcCurApk() {