Fix sending arguments to the admin socket in yggdrasilctl

This commit is contained in:
Neil Alexander 2022-09-24 21:28:09 +01:00
parent 1de587a971
commit c922eba2d8
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
3 changed files with 28 additions and 21 deletions

View File

@ -85,7 +85,7 @@ func run() int {
encoder := json.NewEncoder(conn) encoder := json.NewEncoder(conn)
send := &admin.AdminSocketRequest{} send := &admin.AdminSocketRequest{}
recv := &admin.AdminSocketResponse{} recv := &admin.AdminSocketResponse{}
args := map[string]string{}
for c, a := range cmdLineEnv.args { for c, a := range cmdLineEnv.args {
if c == 0 { if c == 0 {
if strings.HasPrefix(a, "-") { if strings.HasPrefix(a, "-") {
@ -96,15 +96,17 @@ func run() int {
send.Name = a send.Name = a
continue continue
} }
tokens := strings.SplitN(a, "=", 1) tokens := strings.SplitN(a, "=", 2)
switch { switch {
case len(tokens) == 1: case len(tokens) == 1:
panic("incomplete argument supplied") logger.Println("Ignoring invalid argument:", a)
default: default:
send.Arguments[tokens[0]] = tokens[1] args[tokens[0]] = tokens[1]
} }
} }
if send.Arguments, err = json.Marshal(args); err != nil {
panic(err)
}
if err := encoder.Encode(&send); err != nil { if err := encoder.Encode(&send); err != nil {
panic(err) panic(err)
} }
@ -139,7 +141,7 @@ func run() int {
table.SetNoWhiteSpace(true) table.SetNoWhiteSpace(true)
table.SetAutoWrapText(false) table.SetAutoWrapText(false)
switch strings.ToLower(recv.Request.Name) { switch strings.ToLower(send.Name) {
case "list": case "list":
var resp admin.ListResponse var resp admin.ListResponse
if err := json.Unmarshal(recv.Response, &resp); err != nil { if err := json.Unmarshal(recv.Response, &resp); err != nil {

View File

@ -30,16 +30,16 @@ type AdminSocket struct {
} }
type AdminSocketRequest struct { type AdminSocketRequest struct {
Name string `json:"request"` Name string `json:"request"`
Arguments map[string]string `json:"arguments,omitempty"` Arguments json.RawMessage `json:"arguments,omitempty"`
KeepAlive bool `json:"keepalive,omitempty"` KeepAlive bool `json:"keepalive,omitempty"`
} }
type AdminSocketResponse struct { type AdminSocketResponse struct {
Status string `json:"status"` Status string `json:"status"`
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
Request AdminSocketRequest `json:"request"` Request json.RawMessage `json:"request"`
Response json.RawMessage `json:"response"` Response json.RawMessage `json:"response"`
} }
type handler struct { type handler struct {
@ -298,25 +298,26 @@ func (a *AdminSocket) handleRequest(conn net.Conn) {
for { for {
var err error var err error
var buf json.RawMessage var buf json.RawMessage
var req AdminSocketRequest
var resp AdminSocketResponse var resp AdminSocketResponse
if err := func() error { if err := func() error {
if err = decoder.Decode(&buf); err != nil { if err = decoder.Decode(&buf); err != nil {
return fmt.Errorf("Failed to find request") return fmt.Errorf("Failed to find request")
} }
if err = json.Unmarshal(buf, &resp.Request); err != nil { if err = json.Unmarshal(buf, &req); err != nil {
return fmt.Errorf("Failed to unmarshal request") return fmt.Errorf("Failed to unmarshal request")
} }
if resp.Request.Name == "" { if req.Name == "" {
return fmt.Errorf("No request specified") return fmt.Errorf("No request specified")
} }
reqname := strings.ToLower(resp.Request.Name) reqname := strings.ToLower(req.Name)
handler, ok := a.handlers[reqname] handler, ok := a.handlers[reqname]
if !ok { if !ok {
return fmt.Errorf("Unknown action '%s', try 'list' for help", reqname) return fmt.Errorf("Unknown action '%s', try 'list' for help", reqname)
} }
res, err := handler.handler(buf) res, err := handler.handler(req.Arguments)
if err != nil { if err != nil {
return fmt.Errorf("Handler returned error: %w", err) return err
} }
if resp.Response, err = json.Marshal(res); err != nil { if resp.Response, err = json.Marshal(res); err != nil {
return fmt.Errorf("Failed to marshal response: %w", err) return fmt.Errorf("Failed to marshal response: %w", err)
@ -330,7 +331,7 @@ func (a *AdminSocket) handleRequest(conn net.Conn) {
if err = encoder.Encode(resp); err != nil { if err = encoder.Encode(resp); err != nil {
a.log.Debugln("Encode error:", err) a.log.Debugln("Encode error:", err)
} }
if !resp.Request.KeepAlive { if !req.KeepAlive {
break break
} else { } else {
continue continue

View File

@ -4,6 +4,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"runtime" "runtime"
"strings" "strings"
"time" "time"
@ -160,11 +161,14 @@ func (m *nodeinfo) nodeInfoAdminHandler(in json.RawMessage) (interface{}, error)
if err := json.Unmarshal(in, &req); err != nil { if err := json.Unmarshal(in, &req); err != nil {
return nil, err return nil, err
} }
if req.Key == "" {
return nil, fmt.Errorf("No remote public key supplied")
}
var key keyArray var key keyArray
var kbs []byte var kbs []byte
var err error var err error
if kbs, err = hex.DecodeString(req.Key); err != nil { if kbs, err = hex.DecodeString(req.Key); err != nil {
return nil, err return nil, fmt.Errorf("Failed to decode public key: %w", err)
} }
copy(key[:], kbs) copy(key[:], kbs)
ch := make(chan []byte, 1) ch := make(chan []byte, 1)
@ -175,7 +179,7 @@ func (m *nodeinfo) nodeInfoAdminHandler(in json.RawMessage) (interface{}, error)
defer timer.Stop() defer timer.Stop()
select { select {
case <-timer.C: case <-timer.C:
return nil, errors.New("timeout") return nil, errors.New("Timed out waiting for response")
case info := <-ch: case info := <-ch:
var msg json.RawMessage var msg json.RawMessage
if err := msg.UnmarshalJSON(info); err != nil { if err := msg.UnmarshalJSON(info); err != nil {