diff --git a/auth.go b/auth.go index f28d6ef..285e747 100644 --- a/auth.go +++ b/auth.go @@ -22,6 +22,7 @@ import ( "crypto/sha256" "crypto/subtle" "encoding/hex" + "encoding/json" "fmt" "log" "os" @@ -47,6 +48,11 @@ func tokenPath() string { return "token.txt" } +// tokenFile is token.txt's on-disk shape. +type tokenFile struct { + Token string `json:"token"` +} + func randomHex(n int) (string, error) { b := make([]byte, n) if _, err := rand.Read(b); err != nil { @@ -68,15 +74,22 @@ func resolveToken(cfg config) (token string, generated bool, err error) { } path := tokenPath() if data, rerr := os.ReadFile(path); rerr == nil { - if t := strings.TrimSpace(string(data)); t != "" { - return t, false, nil + var tf tokenFile + if jerr := json.Unmarshal(data, &tf); jerr == nil { + if t := strings.TrimSpace(tf.Token); t != "" { + return t, false, nil + } } } t, gerr := randomHex(tokenBytes) if gerr != nil { return "", false, fmt.Errorf("couldn't generate a token: %w", gerr) } - if werr := os.WriteFile(path, []byte(t), 0600); werr != nil { + blob, merr := json.MarshalIndent(tokenFile{Token: t}, "", " ") + if merr != nil { + return "", false, fmt.Errorf("couldn't encode token.txt: %w", merr) + } + if werr := os.WriteFile(path, blob, 0600); werr != nil { return "", false, fmt.Errorf("couldn't save token.txt: %w", werr) } return t, true, nil diff --git a/config.go b/config.go index c491e74..6f8fe39 100644 --- a/config.go +++ b/config.go @@ -16,6 +16,7 @@ package main import ( "crypto/rand" "encoding/hex" + "encoding/json" "fmt" "log" "os" @@ -316,14 +317,22 @@ partner = "" // load a different save. With its own id, the hub keeps seeing the same // partner even if they switch characters, reconnect, or restart the // program. +// clientIDFile is client-id.txt's on-disk shape. +type clientIDFile struct { + ID string `json:"id"` +} + func clientID() string { path := "client-id.txt" if exe, err := os.Executable(); err == nil { path = filepath.Join(filepath.Dir(exe), "client-id.txt") } if data, err := os.ReadFile(path); err == nil { - if id := strings.TrimSpace(string(data)); id != "" { - return id + var f clientIDFile + if jerr := json.Unmarshal(data, &f); jerr == nil { + if id := strings.TrimSpace(f.ID); id != "" { + return id + } } } var b [8]byte @@ -333,7 +342,12 @@ func clientID() string { return fmt.Sprintf("pid-%d", os.Getpid()) } id := hex.EncodeToString(b[:]) - if err := os.WriteFile(path, []byte(id), 0644); err != nil { + blob, merr := json.MarshalIndent(clientIDFile{ID: id}, "", " ") + if merr != nil { + log.Printf("couldn't encode client-id.txt (%v): using a fresh id every startup", merr) + return id + } + if err := os.WriteFile(path, blob, 0644); err != nil { log.Printf("couldn't save client-id.txt (%v): using a fresh id every startup", err) } return id @@ -345,7 +359,7 @@ func writeSampleConfig() { if _, err := os.Stat(path); err == nil { return } - if err := os.WriteFile(path, []byte(sampleConfig), 0644); err != nil { + if err := os.WriteFile(path, []byte(sampleConfig), 0600); err != nil { log.Printf("couldn't write the sample config.toml: %v", err) return }