~james/core

core/spindle/mill/debug_key.go -rw-r--r-- 1.7 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 14 hours 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
package mill

import (
	"context"
	"errors"
	"fmt"

	"github.com/bluesky-social/indigo/atproto/syntax"
	gossh "golang.org/x/crypto/ssh"

	millproto "tangled.org/core/spindle/mill/proto"
	millv1 "tangled.org/core/spindle/mill/proto/gen"
)

// the spindle's own check, the mill only picks the repo
type DebugKeyChecker interface {
	DebugKeyAllowed(ctx context.Context, repoDid syntax.DID, key gossh.PublicKey) bool
}

func (m *Mill) SetDebugKeyChecker(c DebugKeyChecker) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.debugKeys = c
}

func (m *Mill) handleDebugKeyRequest(s *millSession, req *millv1.DebugKeyRequest) {
	resp := &millv1.DebugKeyResponse{RequestId: req.GetRequestId()}
	allowed, err := m.debugKeyAllowed(s, req)
	if err != nil {
		resp.Error = err.Error()
	}
	resp.Allowed = allowed && err == nil
	_ = s.send(&millproto.Message{DebugKeyResp: resp})
}

// the repo comes from the lease this node was given, never from the executor
func (m *Mill) debugKeyAllowed(s *millSession, req *millv1.DebugKeyRequest) (bool, error) {
	m.mu.Lock()
	checker := m.debugKeys
	lease := m.leases[req.GetLeaseId()]
	m.mu.Unlock()
	if checker == nil {
		return false, errors.New("no debug key checker attached")
	}
	if lease == nil || lease.nodeID != s.nodeID || lease.epoch != s.epoch {
		return false, fmt.Errorf("no live lease %q on this node with matching epoch", req.GetLeaseId())
	}
	lease.mu.Lock()
	repo := lease.repoDID
	lease.mu.Unlock()
	repoDid, err := syntax.ParseDID(repo)
	if err != nil {
		return false, fmt.Errorf("lease has no usable repo: %w", err)
	}
	key, err := gossh.ParsePublicKey(req.GetPublicKey())
	if err != nil {
		return false, fmt.Errorf("bad public key: %w", err)
	}
	return checker.DebugKeyAllowed(s.ctx, repoDid, key), nil
}