~welt/murse

ref: db85e43da90177a9ed7275eb7f2d6952407c1466 murse/download.go -rw-r--r-- 2.0 KiB
db85e43dwelt guiprep: adjust logging 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package main

import (
	"crypto/rsa"
	"crypto/sha512"
	"errors"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"

	"github.com/gabriel-vasile/mimetype"
	"github.com/klauspost/compress/zstd"
)

func downloadDevKey() (*rsa.PublicKey, error) {
	b, err := get("https://raw.githubusercontent.com/int-72h/ofatomic/main/ofatomic/ofpublic.pem")
	if err != nil {
		return nil, err
	}

	k, err := parseKey(b)
	if err != nil {
		return nil, err
	}

	return k, nil
}

func get(url string) (*[]byte, error) {
	r, err := http.Get(url)
	if err != nil {
		return nil, err
	}

	defer r.Body.Close()
	b, err := io.ReadAll(r.Body)
	if err != nil {
		return nil, err
	}

	if mimetype.Detect(b).String() == "application/zstd" {
		d, _ := zstd.NewReader(nil)
		defer d.Close()
		bd, err := d.DecodeAll(b, nil)
		if err != nil {
			return nil, err
		}

		defer d.Close()

		return &bd, nil
	}
	return &b, nil
}

func downloadAndVerify(path string, checksum string, lchecksum *string) error {
	ff := filepath.Join(opt.Directory, path)
	if _, err := os.Stat(ff); !os.IsNotExist(err) {
		b, err := os.ReadFile(ff)
		if err != nil {
			return err
		}

		h := sha512.Sum384(b)

		if isProtected(path) && !install && !opt.OverwriteProtected && lchecksum != nil {
			dh, err := base16ToHash(*lchecksum) // <^ if protected and modified
			if err != nil {
				return err
			}

			if *dh == h {
				log.Println("File is protected, will not overwrite: " + ff)
				return nil
			}
		}

		dh, err := base16ToHash(checksum)
		if err != nil {
			return err
		}
		if *dh == h {
			log.Println("File exists and matches hash, skipping: " + ff)
			return nil
		}
	}

	log.Println("Downloading: " + ff)

	err := os.MkdirAll(filepath.Dir(ff), 0777)
	if err != nil && !errors.Is(err, os.ErrExist) {
		return err
	}

	b, err := get(opt.URL + "/" + path)
	if err != nil {
		return err
	}

	t, err := compareBytesHashSum(checksum, b)
	if err != nil {
		return err
	}
	if !t {
		return errors.New("file failed integrity check:" + path)
	}

	os.WriteFile(ff, *b, 0666)
	return nil
}