Skip to content

Commit

Permalink
Add windows support to the self updater (gopasspw#1724)
Browse files Browse the repository at this point in the history
Fixes gopasspw#1722

RELEASE_NOTES=[ENHANCEMENT] Add windows support to the self updater

Signed-off-by: Dominik Schulz <dominik.schulz@gauner.org>
  • Loading branch information
dominikschulz committed Jan 18, 2021
1 parent fd28978 commit 6974917
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 24 deletions.
6 changes: 6 additions & 0 deletions go.sum
Expand Up @@ -104,22 +104,28 @@ github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b h1:tnWgqoOBmInkt5pb
github.com/xrash/smetrics v0.0.0-20200730060457-89a2a8a1fb0b/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae h1:duLSQW+DZ5MsXKX7kc4rXlq6/mmxz4G6ewJuBPlhRe0=
golang.org/x/crypto v0.0.0-20200930160638-afb6bcd081ae/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 h1:iCaAy5bMeEvwANu3YnJfWwI0kWAGkEa2RXPdweI/ysk=
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4 h1:1mMox4TgefDwqluYCv677yNXwlfTkija4owZve/jr78=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
Expand Down
88 changes: 64 additions & 24 deletions internal/updater/extract.go
Expand Up @@ -2,6 +2,7 @@ package updater

import (
"archive/tar"
"archive/zip"
"bytes"
"compress/bzip2"
"compress/gzip"
Expand All @@ -23,55 +24,94 @@ func extractFile(buf []byte, filename, dest string) error {
mode = fi.Mode()
}

if err := os.Remove(dest); err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("unable to remove destination file: %q", err)
}
}

dfh, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_EXCL, mode)
if err != nil {
return errors.Wrapf(err, "Failed to open file: %s", dest)
}
defer func() {
_ = dfh.Close()
}()

var rd io.Reader = bytes.NewReader(buf)
switch filepath.Ext(filename) {
case ".gz":
gzr, err := gzip.NewReader(rd)
if err != nil {
return err
}
rd = gzr
return extractTar(gzr, dfh, dest)
case ".bz2":
rd = bzip2.NewReader(rd)
return extractTar(bzip2.NewReader(rd), dfh, dest)
case ".zip":
return fmt.Errorf("zip archives are not supported, yet")
return extractZip(buf, dfh, dest)
default:
return fmt.Errorf("unsupported")
}
}

if err := os.Remove(dest); err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("unable to remove destination file: %q", err)
}
func extractZip(buf []byte, dfh io.WriteCloser, dest string) error {
zrd, err := zip.NewReader(bytes.NewReader(buf), int64(len(buf)))
if err != nil {
return err
}

dfh, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_EXCL, mode)
if err != nil {
return errors.Wrapf(err, "Failed to open file: %s", dest)
for i := 0; i < len(zrd.File); i++ {
if zrd.File[i].Name != "gopass.exe" {
continue
}

file, err := zrd.File[i].Open()
if err != nil {
return errors.Wrapf(err, "failed to read from zip file")
}

n, err := io.Copy(dfh, file)
if err != nil {
dfh.Close()
os.Remove(dest)
return errors.Wrapf(err, "failed to read gopass.exe from zip file")
}
// success
debug.Log("wrote %d bytes to %v", n, dest)
return nil
}
defer func() {
_ = dfh.Close()
}()

return errors.Errorf("file not found in archive")
}

func extractTar(rd io.Reader, dfh io.WriteCloser, dest string) error {
tarReader := tar.NewReader(rd)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return errors.Wrapf(err, "Failed to read from tar file")
return errors.Wrapf(err, "failed to read from tar file")
}
name := filepath.Base(header.Name)
if header.Typeflag == tar.TypeReg && name == "gopass" {
n, err := io.Copy(dfh, tarReader)
if err != nil {
dfh.Close()
os.Remove(dest)
return errors.Wrapf(err, "Failed to read gopass from tar file")
}
// success
debug.Log("wrote %d bytes to %v", n, dest)
return nil
if header.Typeflag != tar.TypeReg {
continue
}
if name != "gopass" {
continue
}

n, err := io.Copy(dfh, tarReader)
if err != nil {
dfh.Close()
os.Remove(dest)
return errors.Wrapf(err, "Failed to read gopass from tar file")
}
// success
debug.Log("wrote %d bytes to %v", n, dest)
return nil
}
return errors.Errorf("file not found in archive")
}

0 comments on commit 6974917

Please sign in to comment.