carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package hostfloor
2
3import (
4 "context"
5 "crypto/ed25519"
6 "errors"
7 "github.com/aws/smithy-go"
8 "github.com/carlosframework/platform/internal/release"
9 "net"
10 "os"
11)
12
13func Offline(err error) bool {
14 if errors.Is(err, context.DeadlineExceeded) {
15 return true
16 }
17 var network net.Error
18 if errors.As(err, &network) {
19 return true
20 }
21 var api smithy.APIError
22 if errors.As(err, &api) {
23 switch api.ErrorCode() {
24 case "SlowDown", "ServiceUnavailable", "InternalError":
25 return true
26 }
27 }
28 return false
29}
30func CheckRemote(ctx context.Context, s release.Store, pub ed25519.PublicKey, bucket string, local Verified) error {
31 remote, err := Read(ctx, s, pub, bucket)
32 if err != nil {
33 if Offline(err) {
34 return nil
35 }
36 return err
37 }
38 if remote.Digest != local.Digest {
39 return ErrFloor
40 }
41 return nil
42}
43
44// CheckRemotePolicy is guard-exec's comparison of the local policy with the
45// published floor (D1). An armed policy is the prospective floor, persisted
46// before publication, so a store holding neither floor object is the
47// expected state and the local policy, already enforced, stands (Opus 8b
48// review I-1). Every other answer refuses unless it matches: a half-written
49// pair, a malformed or unauthorized object, a different digest, or no
50// remote floor at all once the policy is enforced. An unreachable store is
51// offline, as in CheckRemote.
52func CheckRemotePolicy(ctx context.Context, s release.Store, pub ed25519.PublicKey, bucket string, p Policy, local Verified) error {
53 raw, _, rawErr := s.Get(ctx, Key)
54 if rawErr != nil {
55 if Offline(rawErr) {
56 return nil
57 }
58 if p.Mode == "armed" && errors.Is(rawErr, os.ErrNotExist) {
59 _, _, authErr := s.Get(ctx, AuthKey)
60 if errors.Is(authErr, os.ErrNotExist) {
61 return nil
62 }
63 }
64 // A later offline read cannot erase the first definite refusal.
65 return rawErr
66 }
67 auth, _, authErr := s.Get(ctx, AuthKey)
68 if authErr != nil {
69 if Offline(authErr) {
70 return nil
71 }
72 return authErr
73 }
74 remote, err := Verify(pub, bucket, raw, auth)
75 if err != nil {
76 return err
77 }
78 if remote.Digest != local.Digest {
79 return ErrFloor
80 }
81 return nil
82}
83