]> Cypherpunks.ru repositories - gocheese.git/blob - integrity.go
Fix download links
[gocheese.git] / integrity.go
1 /*
2 GoCheese -- Python private package repository and caching proxy
3 Copyright (C) 2019-2021 Sergey Matveev <stargrave@stargrave.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 3 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 package main
19
20 import (
21         "bufio"
22         "bytes"
23         "crypto/sha256"
24         "fmt"
25         "hash"
26         "io"
27         "io/ioutil"
28         "log"
29         "os"
30         "path/filepath"
31         "strings"
32
33         "golang.org/x/crypto/blake2b"
34 )
35
36 func checkFile(
37         pkgName, fn, fnHash, hasherName string,
38         hasher hash.Hash, digest []byte,
39 ) bool {
40         expected, err := ioutil.ReadFile(fnHash)
41         if err != nil {
42                 log.Fatal(err)
43         }
44         fd, err := os.Open(fn)
45         if err != nil {
46                 if os.IsNotExist(err) {
47                         return true
48                 }
49                 log.Fatal(err)
50         }
51         _, err = io.Copy(hasher, bufio.NewReader(fd))
52         fd.Close()
53         if err != nil {
54                 log.Fatal(err)
55         }
56         isEqual := bytes.Compare(hasher.Sum(digest[:0]), expected) == 0
57         hasher.Reset()
58         if isEqual {
59                 fmt.Println("GOOD", hasherName, pkgName)
60                 return true
61         }
62         fmt.Println("BAD", hasherName, pkgName)
63         return false
64 }
65
66 func goodIntegrity() bool {
67         dirs, err := ioutil.ReadDir(Root)
68         if err != nil {
69                 log.Fatal(err)
70         }
71         hasherSHA256 := sha256.New()
72         hasherBLAKE2b256 := blake2b256New()
73         digestSHA256 := make([]byte, sha256.Size)
74         digestBLAKE2b256 := make([]byte, blake2b.Size256)
75         isGood := true
76         var pkgName string
77         for _, dir := range dirs {
78                 files, err := ioutil.ReadDir(filepath.Join(Root, dir.Name()))
79                 if err != nil {
80                         log.Fatal(err)
81                 }
82                 for _, file := range files {
83                         if strings.HasSuffix(file.Name(), "."+HashAlgoSHA256) {
84                                 pkgName = strings.TrimSuffix(file.Name(), "."+HashAlgoSHA256)
85                                 if !checkFile(
86                                         pkgName,
87                                         filepath.Join(Root, dir.Name(), pkgName),
88                                         filepath.Join(Root, dir.Name(), file.Name()),
89                                         "SHA256", hasherSHA256, digestSHA256,
90                                 ) {
91                                         isGood = false
92                                 }
93                                 continue
94                         }
95                         if strings.HasSuffix(file.Name(), "."+HashAlgoBLAKE2b256) {
96                                 pkgName = strings.TrimSuffix(file.Name(), "."+HashAlgoBLAKE2b256)
97                                 if !checkFile(
98                                         pkgName,
99                                         filepath.Join(Root, dir.Name(), pkgName),
100                                         filepath.Join(Root, dir.Name(), file.Name()),
101                                         "BLAKE2b-256", hasherBLAKE2b256, digestBLAKE2b256,
102                                 ) {
103                                         isGood = false
104                                 }
105                         }
106                 }
107         }
108         return isGood
109 }