Archived
76 lines
1.8 KiB
Go
76 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
type ConfigFile struct {
|
|
ListenPort string `json:"listen_port"`
|
|
DataDir string `json:"data_dir"`
|
|
Peers []string `json:"peers"`
|
|
Files map[string][]string `json:"files"` // filename -> list of allowed public keys
|
|
}
|
|
|
|
type Config struct {
|
|
ListenPort string
|
|
DataDir string
|
|
Peers []string
|
|
Files map[string][]ed25519.PublicKey // filename -> parsed public keys
|
|
}
|
|
|
|
func LoadConfig(path string) (*Config, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read config file: %w", err)
|
|
}
|
|
|
|
var cf ConfigFile
|
|
if err := json.Unmarshal(data, &cf); err != nil {
|
|
return nil, fmt.Errorf("failed to parse config file: %w", err)
|
|
}
|
|
|
|
if cf.ListenPort == "" {
|
|
cf.ListenPort = "8080"
|
|
}
|
|
|
|
if cf.DataDir == "" {
|
|
return nil, fmt.Errorf("data_dir is required")
|
|
}
|
|
|
|
if len(cf.Files) == 0 {
|
|
return nil, fmt.Errorf("at least one file must be configured")
|
|
}
|
|
|
|
files := make(map[string][]ed25519.PublicKey)
|
|
for filename, keyStrs := range cf.Files {
|
|
if len(keyStrs) == 0 {
|
|
return nil, fmt.Errorf("file %q has no allowed keys", filename)
|
|
}
|
|
|
|
var keys []ed25519.PublicKey
|
|
for _, keyStr := range keyStrs {
|
|
key, err := ParseOpenSSHEd25519PublicKey(keyStr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid key for file %q: %w", filename, err)
|
|
}
|
|
keys = append(keys, key)
|
|
}
|
|
files[filename] = keys
|
|
}
|
|
|
|
return &Config{
|
|
ListenPort: cf.ListenPort,
|
|
DataDir: cf.DataDir,
|
|
Peers: cf.Peers,
|
|
Files: files,
|
|
}, nil
|
|
}
|
|
|
|
// GetAllowedKeys returns the allowed keys for a given filename, or nil if not configured.
|
|
func (c *Config) GetAllowedKeys(filename string) []ed25519.PublicKey {
|
|
return c.Files[filename]
|
|
}
|