]> Cypherpunks.ru repositories - gocheese.git/blob - integrity.go
More convenient trusted-host
[gocheese.git] / integrity.go
1 /*
2 GoCheese -- Python private package repository and caching proxy
3 Copyright (C) 2019-2022 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         "log"
28         "os"
29         "path/filepath"
30         "strings"
31
32         "golang.org/x/crypto/blake2b"
33 )
34
35 func checkFile(
36         pkgName, fn, fnHash, hasherName string,
37         hasher hash.Hash, digest []byte,
38 ) bool {
39         expected, err := os.ReadFile(fnHash)
40         if err != nil {
41                 log.Fatal(err)
42         }
43         fd, err := os.Open(fn)
44         if err != nil {
45                 if os.IsNotExist(err) {
46                         return true
47                 }
48                 log.Fatal(err)
49         }
50         _, err = io.Copy(hasher, bufio.NewReader(fd))
51         fd.Close()
52         if err != nil {
53                 log.Fatal(err)
54         }
55         isEqual := bytes.Compare(hasher.Sum(digest[:0]), expected) == 0
56         hasher.Reset()
57         if isEqual {
58                 fmt.Println("GOOD", hasherName, pkgName)
59                 return true
60         }
61         fmt.Println("BAD", hasherName, pkgName)
62         return false
63 }
64
65 func goodIntegrity() bool {
66         dirs, err := os.ReadDir(Root)
67         if err != nil {
68                 log.Fatal(err)
69         }
70         hasherSHA256 := sha256.New()
71         hasherBLAKE2b256 := blake2b256New()
72         digestSHA256 := make([]byte, sha256.Size)
73         digestBLAKE2b256 := make([]byte, blake2b.Size256)
74         isGood := true
75         var pkgName string
76         for _, dir := range dirs {
77                 files, err := os.ReadDir(filepath.Join(Root, dir.Name()))
78                 if err != nil {
79                         log.Fatal(err)
80                 }
81                 for _, file := range files {
82                         if strings.HasSuffix(file.Name(), "."+HashAlgoSHA256) {
83                                 pkgName = strings.TrimSuffix(file.Name(), "."+HashAlgoSHA256)
84                                 if !checkFile(
85                                         pkgName,
86                                         filepath.Join(Root, dir.Name(), pkgName),
87                                         filepath.Join(Root, dir.Name(), file.Name()),
88                                         "SHA256", hasherSHA256, digestSHA256,
89                                 ) {
90                                         isGood = false
91                                 }
92                                 continue
93                         }
94                         if strings.HasSuffix(file.Name(), "."+HashAlgoBLAKE2b256) {
95                                 pkgName = strings.TrimSuffix(file.Name(), "."+HashAlgoBLAKE2b256)
96                                 if !checkFile(
97                                         pkgName,
98                                         filepath.Join(Root, dir.Name(), pkgName),
99                                         filepath.Join(Root, dir.Name(), file.Name()),
100                                         "BLAKE2b-256", hasherBLAKE2b256, digestBLAKE2b256,
101                                 ) {
102                                         isGood = false
103                                 }
104                         }
105                 }
106         }
107         return isGood
108 }