implement full request flow
This commit is contained in:
parent
cb20155b1e
commit
affa5919f7
7 changed files with 214 additions and 60 deletions
|
@ -29,10 +29,12 @@ import (
|
|||
func newNewCommand() *cobra.Command {
|
||||
// TODO(jaredallard): Support setting the name of the machine.
|
||||
return &cobra.Command{
|
||||
Use: "new",
|
||||
Use: "new <machineName>",
|
||||
Short: "Create a new machine",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
name := args[0] // Checked by [cobra.ExactArgs] above.
|
||||
|
||||
db, err := db.New(cmd.Context())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open DB: %w", err)
|
||||
|
@ -54,7 +56,7 @@ func newNewCommand() *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := db.Machine.Create().
|
||||
if err := db.Machine.Create().SetName(name).
|
||||
SetID(fprint).SetPublicKey(m.PublicKey).
|
||||
Exec(cmd.Context()); err != nil {
|
||||
return fmt.Errorf("failed to write to DB: %w", err)
|
||||
|
|
|
@ -21,7 +21,9 @@ import (
|
|||
"bytes"
|
||||
"crypto/ed25519"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
pbgrpcv1 "git.rgst.io/homelab/klefki/internal/server/grpc/generated/go/rgst/klefki/v1"
|
||||
|
@ -33,6 +35,21 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// nopWriteCloser is a no-op [io.WriteCloser]
|
||||
type nopWriteCloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// Close implements [io.Closer]
|
||||
func (nwc nopWriteCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// newNopWriteCloser creates a new nopWriteCloser
|
||||
func newNopWriteCloser(w io.Writer) *nopWriteCloser {
|
||||
return &nopWriteCloser{w}
|
||||
}
|
||||
|
||||
// newRequestsCommand creates a requests [cobra.Command]
|
||||
func newRequestsCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
|
@ -40,18 +57,19 @@ func newRequestsCommand() *cobra.Command {
|
|||
Short: "Make requests to a klefki server",
|
||||
}
|
||||
cmd.AddCommand(
|
||||
newGetKeyRequestCommand(),
|
||||
newGetKeyCommand(),
|
||||
newListSessionsCommand(),
|
||||
newSubmitKeyCommand(),
|
||||
)
|
||||
flags := cmd.Flags()
|
||||
flags.String("hostname", "127.0.0.1:5300", "hostname of the klefki server to connect to")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// newGetKeyRequestCommand creates a getkeyrequest [cobra.Command]
|
||||
func newGetKeyRequestCommand() *cobra.Command {
|
||||
// newGetKeyCommand creates a getkeyrequest [cobra.Command]
|
||||
func newGetKeyCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "getkeyrequest",
|
||||
Use: "getkey",
|
||||
Short: "Get the passphrase for the given machine",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
|
@ -84,11 +102,17 @@ func newGetKeyRequestCommand() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer kcclose() //nolint:errcheck // Why: Best effort
|
||||
defer kcclose() //nolint:errcheck // Why: Btiest effort
|
||||
|
||||
tsResp, err := kc.GetTime(cmd.Context(), &pbgrpcv1.GetTimeRequest{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to server to get time: %w", err)
|
||||
}
|
||||
|
||||
req := &pbgrpcv1.GetKeyRequest{}
|
||||
req.SetMachineId(machineID)
|
||||
req.SetNonce(uuid.New().String())
|
||||
req.SetSignedAt(tsResp.GetTime())
|
||||
req.SetSignature(ed25519.Sign(pk, []byte(req.GetNonce())))
|
||||
|
||||
resp, err := kc.GetKey(cmd.Context(), req)
|
||||
|
@ -125,7 +149,7 @@ func newListSessionsCommand() *cobra.Command {
|
|||
Short: "Return a list of all machines waiting for a key to be provided",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
kc, kcclose, err := client.Dial(cmd.Flag("hostname").Value.String())
|
||||
kc, kcclose, err := client.Dial(cmd.Parent().Flag("hostname").Value.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -143,11 +167,74 @@ func newListSessionsCommand() *cobra.Command {
|
|||
}
|
||||
|
||||
tw := tabwriter.NewWriter(os.Stdout, 2, 2, 2, ' ', 0)
|
||||
fmt.Fprint(tw, "FINGERPRINT\n")
|
||||
fmt.Fprint(tw, "FINGERPRINT\tLAST ASKED\n")
|
||||
for _, m := range machines {
|
||||
fmt.Fprintf(tw, "%s\n", m.GetId())
|
||||
fmt.Fprintf(tw, "%s\t%s\n", m.GetId(), m.GetLastAsked())
|
||||
}
|
||||
return tw.Flush()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// newSubmitKeyCommand creates a submitekey [cobra.Command]
|
||||
func newSubmitKeyCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "submitkey <machineID> <passphrase>",
|
||||
Short: "Submit a passphrase to a given machine by its ID",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
machineID := args[0]
|
||||
// TODO(jaredallard): don't expect to be passed
|
||||
passphrase := args[1]
|
||||
|
||||
kc, kcclose, err := client.Dial(cmd.Parent().Flag("hostname").Value.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer kcclose() //nolint:errcheck // Why: Best effort
|
||||
|
||||
resp, err := kc.ListSessions(cmd.Context(), &pbgrpcv1.ListSessionsRequest{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get key from server: %w", err)
|
||||
}
|
||||
|
||||
machines := resp.GetMachines()
|
||||
|
||||
var machine *pbgrpcv1.Machine
|
||||
for _, m := range machines {
|
||||
if m.GetId() == machineID {
|
||||
machine = m
|
||||
break
|
||||
}
|
||||
}
|
||||
if machine == nil {
|
||||
return fmt.Errorf("no sessions found for %q", machineID)
|
||||
}
|
||||
|
||||
pubKey, err := sign.PublicKeyFromBytes(machine.GetPublicKey())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert machine's public key to encryption public key: %w", err)
|
||||
}
|
||||
|
||||
enc, err := sign.NewEncryptor(nil, 1024)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create decryptor: %w", err)
|
||||
}
|
||||
|
||||
if err := enc.AddRecipient(pubKey); err != nil {
|
||||
return fmt.Errorf("failed to set private key on decryptor: %w", err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := enc.Encrypt(strings.NewReader(passphrase), newNopWriteCloser(&buf)); err != nil {
|
||||
return fmt.Errorf("failed to decrypt session ID: %w", err)
|
||||
}
|
||||
|
||||
req := &pbgrpcv1.SubmitKeyRequest{}
|
||||
req.SetEncKey(buf.Bytes())
|
||||
req.SetMachineId(machineID)
|
||||
_, err = kc.SubmitKey(cmd.Context(), req)
|
||||
return err
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
2
internal/db/ent/migrate/schema.go
generated
2
internal/db/ent/migrate/schema.go
generated
|
@ -13,7 +13,7 @@ var (
|
|||
{Name: "id", Type: field.TypeString},
|
||||
{Name: "name", Type: field.TypeString, Unique: true},
|
||||
{Name: "public_key", Type: field.TypeBytes},
|
||||
{Name: "created_at", Type: field.TypeString, Default: "2025-03-01T23:41:53Z"},
|
||||
{Name: "created_at", Type: field.TypeString, Default: "2025-03-07T05:15:58Z"},
|
||||
}
|
||||
// MachinesTable holds the schema information for the "machines" table.
|
||||
MachinesTable = &schema.Table{
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
_ "google.golang.org/protobuf/types/gofeaturespb"
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -444,6 +445,7 @@ type Machine struct {
|
|||
state protoimpl.MessageState `protogen:"opaque.v1"`
|
||||
xxx_hidden_Id *string `protobuf:"bytes,1,opt,name=id"`
|
||||
xxx_hidden_PublicKey []byte `protobuf:"bytes,2,opt,name=public_key,json=publicKey"`
|
||||
xxx_hidden_LastAsked *string `protobuf:"bytes,3,opt,name=last_asked,json=lastAsked"`
|
||||
XXX_raceDetectHookData protoimpl.RaceDetectHookData
|
||||
XXX_presence [1]uint32
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
@ -492,9 +494,19 @@ func (x *Machine) GetPublicKey() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *Machine) GetLastAsked() string {
|
||||
if x != nil {
|
||||
if x.xxx_hidden_LastAsked != nil {
|
||||
return *x.xxx_hidden_LastAsked
|
||||
}
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Machine) SetId(v string) {
|
||||
x.xxx_hidden_Id = &v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 2)
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 3)
|
||||
}
|
||||
|
||||
func (x *Machine) SetPublicKey(v []byte) {
|
||||
|
@ -502,7 +514,12 @@ func (x *Machine) SetPublicKey(v []byte) {
|
|||
v = []byte{}
|
||||
}
|
||||
x.xxx_hidden_PublicKey = v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 2)
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 3)
|
||||
}
|
||||
|
||||
func (x *Machine) SetLastAsked(v string) {
|
||||
x.xxx_hidden_LastAsked = &v
|
||||
protoimpl.X.SetPresent(&(x.XXX_presence[0]), 2, 3)
|
||||
}
|
||||
|
||||
func (x *Machine) HasId() bool {
|
||||
|
@ -519,6 +536,13 @@ func (x *Machine) HasPublicKey() bool {
|
|||
return protoimpl.X.Present(&(x.XXX_presence[0]), 1)
|
||||
}
|
||||
|
||||
func (x *Machine) HasLastAsked() bool {
|
||||
if x == nil {
|
||||
return false
|
||||
}
|
||||
return protoimpl.X.Present(&(x.XXX_presence[0]), 2)
|
||||
}
|
||||
|
||||
func (x *Machine) ClearId() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0)
|
||||
x.xxx_hidden_Id = nil
|
||||
|
@ -529,11 +553,17 @@ func (x *Machine) ClearPublicKey() {
|
|||
x.xxx_hidden_PublicKey = nil
|
||||
}
|
||||
|
||||
func (x *Machine) ClearLastAsked() {
|
||||
protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 2)
|
||||
x.xxx_hidden_LastAsked = nil
|
||||
}
|
||||
|
||||
type Machine_builder struct {
|
||||
_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.
|
||||
|
||||
Id *string
|
||||
PublicKey []byte
|
||||
LastAsked *string
|
||||
}
|
||||
|
||||
func (b0 Machine_builder) Build() *Machine {
|
||||
|
@ -541,13 +571,17 @@ func (b0 Machine_builder) Build() *Machine {
|
|||
b, x := &b0, m0
|
||||
_, _ = b, x
|
||||
if b.Id != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 2)
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 3)
|
||||
x.xxx_hidden_Id = b.Id
|
||||
}
|
||||
if b.PublicKey != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 2)
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 3)
|
||||
x.xxx_hidden_PublicKey = b.PublicKey
|
||||
}
|
||||
if b.LastAsked != nil {
|
||||
protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 2, 3)
|
||||
x.xxx_hidden_LastAsked = b.LastAsked
|
||||
}
|
||||
return m0
|
||||
}
|
||||
|
||||
|
@ -787,48 +821,50 @@ var file_rgst_klefki_v1_kelfki_proto_rawDesc = string([]byte{
|
|||
0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07,
|
||||
0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x65,
|
||||
0x6e, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x38, 0x0a, 0x07,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x57, 0x0a, 0x07,
|
||||
0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x4b, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33,
|
||||
0x0a, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x17, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69,
|
||||
0x6e, 0x65, 0x73, 0x22, 0x4a, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69,
|
||||
0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x61, 0x63,
|
||||
0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x65, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x22,
|
||||
0x13, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x32, 0xd1, 0x02, 0x0a, 0x0d, 0x4b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x53,
|
||||
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d,
|
||||
0x65, 0x12, 0x1e, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x47, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x2e, 0x72,
|
||||
0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, 0x67,
|
||||
0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x61,
|
||||
0x73, 0x6b, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74,
|
||||
0x41, 0x73, 0x6b, 0x65, 0x64, 0x22, 0x4b, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a,
|
||||
0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x17, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e,
|
||||
0x65, 0x73, 0x22, 0x4a, 0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e,
|
||||
0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68,
|
||||
0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x65, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x13,
|
||||
0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x32, 0xd1, 0x02, 0x0a, 0x0d, 0x4b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x53, 0x65,
|
||||
0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x12, 0x1e, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1f, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x47, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x2e, 0x72, 0x67,
|
||||
0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0c, 0x4c,
|
||||
0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x67,
|
||||
0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x24, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74,
|
||||
0x4b, 0x65, 0x79, 0x12, 0x20, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b,
|
||||
0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65,
|
||||
0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3f, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x2e,
|
||||
0x72, 0x67, 0x73, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
|
||||
0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f,
|
||||
0x67, 0x6f, 0x2f, 0x72, 0x67, 0x73, 0x74, 0x2f, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2f, 0x76,
|
||||
0x31, 0x92, 0x03, 0x05, 0xd2, 0x3e, 0x02, 0x10, 0x03, 0x62, 0x08, 0x65, 0x64, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x70, 0xe8, 0x07,
|
||||
0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, 0x67, 0x73,
|
||||
0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4b,
|
||||
0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0c, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x67, 0x73,
|
||||
0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74,
|
||||
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x24, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b,
|
||||
0x65, 0x79, 0x12, 0x20, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66,
|
||||
0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3f, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x2e, 0x72,
|
||||
0x67, 0x73, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f,
|
||||
0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x67,
|
||||
0x6f, 0x2f, 0x72, 0x67, 0x73, 0x74, 0x2f, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2f, 0x76, 0x31,
|
||||
0x92, 0x03, 0x05, 0xd2, 0x3e, 0x02, 0x10, 0x03, 0x62, 0x08, 0x65, 0x64, 0x69, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x70, 0xe8, 0x07,
|
||||
})
|
||||
|
||||
var file_rgst_klefki_v1_kelfki_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
|
||||
|
|
|
@ -8,6 +8,7 @@ package v1
|
|||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
|
|
|
@ -28,6 +28,7 @@ message ListSessionsRequest {}
|
|||
message Machine {
|
||||
string id = 1;
|
||||
bytes public_key = 2;
|
||||
string last_asked = 3;
|
||||
}
|
||||
|
||||
message ListSessionsResponse {
|
||||
|
|
|
@ -84,6 +84,8 @@ func (s *Server) Run(ctx context.Context) error {
|
|||
return fmt.Errorf("failed to open DB: %w", err)
|
||||
}
|
||||
|
||||
// TODO(jaredallard): Clean up expired sessions after X time period.
|
||||
|
||||
s.gs = grpc.NewServer()
|
||||
pbgrpcv1.RegisterKlefkiServiceServer(s.gs, s)
|
||||
reflection.Register(s.gs)
|
||||
|
@ -100,10 +102,21 @@ func (s *Server) Run(ctx context.Context) error {
|
|||
// GetTime implements the GetTime RPC
|
||||
func (s *Server) GetTime(_ context.Context, req *pbgrpcv1.GetTimeRequest) (*pbgrpcv1.GetTimeResponse, error) {
|
||||
resp := &pbgrpcv1.GetTimeResponse{}
|
||||
resp.SetTime(time.Now().UTC().Format(time.RFC3339Nano))
|
||||
resp.SetTime(time.Now().Format(time.RFC3339Nano))
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// SubmitKey implements the SubmitKey RPC
|
||||
func (s *Server) SubmitKey(ctx context.Context, req *pbgrpcv1.SubmitKeyRequest) (*pbgrpcv1.SubmitKeyResponse, error) {
|
||||
machineID := req.GetMachineId()
|
||||
if _, ok := s.ses[machineID]; !ok {
|
||||
return nil, fmt.Errorf("failed to find machine ID %q", machineID)
|
||||
}
|
||||
|
||||
s.ses[machineID].EncKey = req.GetEncKey()
|
||||
return &pbgrpcv1.SubmitKeyResponse{}, nil
|
||||
}
|
||||
|
||||
// GetKey implements the GetKey RPC
|
||||
func (s *Server) GetKey(ctx context.Context, req *pbgrpcv1.GetKeyRequest) (*pbgrpcv1.GetKeyResponse, error) {
|
||||
resp := &pbgrpcv1.GetKeyResponse{}
|
||||
|
@ -113,6 +126,7 @@ func (s *Server) GetKey(ctx context.Context, req *pbgrpcv1.GetKeyRequest) (*pbgr
|
|||
if err != nil || ts.IsZero() {
|
||||
return nil, fmt.Errorf("failed to parsed signed at %q: %w", req.GetSignedAt(), err)
|
||||
}
|
||||
ts = ts.UTC() // Always operate with UTC time.
|
||||
sig := req.GetSignature()
|
||||
|
||||
machine, err := s.db.Machine.Get(ctx, req.GetMachineId())
|
||||
|
@ -138,11 +152,21 @@ func (s *Server) GetKey(ctx context.Context, req *pbgrpcv1.GetKeyRequest) (*pbgr
|
|||
return nil, fmt.Errorf("failed to add instance public key to encryptor: %w", err)
|
||||
}
|
||||
|
||||
// Track the last time the machine asked for a key. This is what backs
|
||||
// the sessions api
|
||||
if _, ok := s.ses[machine.ID]; !ok {
|
||||
s.ses[machine.ID] = &Session{}
|
||||
}
|
||||
s.ses[machine.ID].LastAsked = time.Now()
|
||||
|
||||
if len(s.ses[machine.ID].EncKey) == 0 {
|
||||
return nil, fmt.Errorf("key not available")
|
||||
}
|
||||
|
||||
resp.SetEncKey(s.ses[machine.ID].EncKey)
|
||||
|
||||
// Reset the session
|
||||
delete(s.ses, machine.ID)
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
@ -157,7 +181,10 @@ func (s *Server) ListSessions(ctx context.Context, _ *pbgrpcv1.ListSessionsReque
|
|||
return nil, fmt.Errorf("failed to get machine %q: %w", machineID, err)
|
||||
}
|
||||
|
||||
grpcMachines = append(grpcMachines, machines.GRPCMachine(machine))
|
||||
// If the machine asked recently, return it
|
||||
gMachine := machines.GRPCMachine(machine)
|
||||
gMachine.SetLastAsked(s.ses[machineID].LastAsked.Format(time.RFC3339Nano))
|
||||
grpcMachines = append(grpcMachines, gMachine)
|
||||
}
|
||||
|
||||
resp.SetMachines(grpcMachines)
|
||||
|
|
Loading…
Add table
Reference in a new issue