blob: a0cea61351b9ff09c01f62521e9e5b7233feabcd [file] [log] [blame]
Serge Bazanskiec71cb52019-08-22 18:13:13 +02001package main
2
3import (
4 "context"
5 "encoding/hex"
6 "fmt"
7 "sync"
8 "time"
9
10 pb "code.hackerspace.pl/hscloud/bgpwtf/cccampix/proto"
11 "code.hackerspace.pl/hscloud/bgpwtf/cccampix/verifier/model"
12 "github.com/golang/glog"
13 "google.golang.org/grpc/codes"
14 "google.golang.org/grpc/status"
15)
16
17type pgp struct {
18 pgpc pb.PGPEncryptorClient
19}
20
21func newPGP(pgpc pb.PGPEncryptorClient) (*pgp, error) {
22 return &pgp{
23 pgpc: pgpc,
24 }, nil
25}
26
27func (p *pgp) Name() string {
28 return "PGP"
29}
30
31func (p *pgp) NextRun(now time.Time, lastRun bool) time.Time {
32 if lastRun {
33 return now.Add(1 * time.Minute)
34 }
35 return now.Add(15 * time.Minute)
36}
37
38func (p *pgp) RunAll(ctx context.Context, m model.Model) error {
39 keys, err := m.GetPGPKeysRequiringAttention(ctx)
40 if err != nil {
41 return fmt.Errorf("GetPGPKeysRequiringAttention: %v", err)
42 }
43
44 if len(keys) == 0 {
45 return nil
46 }
47
48 s := make(chan struct{}, 20)
49 errC := make(chan error, len(keys))
50 knownC := make(chan *model.PeerPGPKey, len(keys))
51 unknownC := make(chan *model.PeerPGPKey, len(keys))
52
53 var wg sync.WaitGroup
54 wg.Add(len(keys))
55
56 for _, key := range keys {
57 go func(k *model.PeerPGPKey) {
58 s <- struct{}{}
59 defer func() {
60 wg.Done()
61 <-s
62 }()
63
64 glog.Infof("PGP: Processing %v", *k)
65
66 // HACK(q3k)
67 if k.State == "known" {
68 knownC <- k
69 return
70 }
71
72 fp, err := hex.DecodeString(k.Fingerprint)
73 if err != nil {
74 errC <- fmt.Errorf("could not decode fingerprint %q: %v", k.Fingerprint, err)
75 return
76 }
77
78 req := &pb.KeyInfoRequest{
79 Fingerprint: fp,
80 Caching: pb.KeyInfoRequest_CACHING_FORCE_REMOTE,
81 }
82
83 _, err = p.pgpc.KeyInfo(ctx, req)
84 s, ok := status.FromError(err)
85 switch {
86 case err == nil:
87 knownC <- k
88 case ok && s.Code() == codes.NotFound:
89 unknownC <- k
90 default:
Serge Bazanskief937472019-08-29 14:53:18 +020091 unknownC <- k
Serge Bazanskiec71cb52019-08-22 18:13:13 +020092 errC <- err
93 }
94 }(key)
95 }
96
97 wg.Wait()
98 close(errC)
99 close(knownC)
100 close(unknownC)
101
102 pcr := []*model.PeerCheckResult{}
103
104 positive := []string{}
105 for p := range knownC {
106 positive = append(positive, p.Fingerprint)
107 pcr = append(pcr, &model.PeerCheckResult{
108 PeerASN: p.PeerASN,
109 CheckName: "pgp",
110 Time: time.Now(),
111 Status: model.PeerCheckStatus_Okay,
112 })
113 }
114 negative := []string{}
115 for n := range unknownC {
116 negative = append(negative, n.Fingerprint)
117 pcr = append(pcr, &model.PeerCheckResult{
118 PeerASN: n.PeerASN,
119 CheckName: "pgp",
120 Time: time.Now(),
121 Status: model.PeerCheckStatus_Failed,
122 Message: fmt.Sprintf("key %q not found on keyservers", n.Fingerprint),
123 })
124 }
125
126 glog.Infof("%v, %v", positive, negative)
127
128 if len(positive) > 0 || len(negative) > 0 {
129 err := m.ValidatePGPKeys(ctx, positive, negative)
130 if err != nil {
131 return fmt.Errorf("ValidatePGPKeys(%v, %v): %v", positive, negative, err)
132 }
133 }
134
135 if len(pcr) > 0 {
136 err = m.SubmitPeerCheckResults(ctx, "pgp", pcr)
137 if err != nil {
138 return err
139 }
140 }
141
142 errs := []error{}
143 for err := range errC {
144 errs = append(errs, err)
145 }
146
147 if len(errs) > 0 {
148 glog.Errorf("Errors while processing keys: %v", errs)
149 return fmt.Errorf("Errors ocurred while processing keys")
150 }
151
152 return nil
153
154}