2024-04-18 01:12:01 +00:00
package configuration
import (
"encoding/json"
"fmt"
"os"
)
type HypdConfiguration struct {
2024-04-18 17:22:03 +00:00
NetworkInterface string ` json:"networkInterface" ` // The network interface that the eBPF program attaches to
2024-04-18 01:12:01 +00:00
PreSharedKeyDirectory string ` json:"preSharedKeyDirectory" ` // hypd will load all *.secret files from this directory
2024-04-18 17:22:03 +00:00
SuccessAction string ` json:"successAction" ` // The action to take for a successful knock, each argument is a separate string
TimeoutSeconds int ` json:"timeoutSeconds" ` // If > 0, once a knock sequence has been successful this value will count down and when it reaches 0, it will perform the TimeoutAction on the client
TimeoutAction string ` json:"timeoutAction" ` // The action to take after TimeoutSeconds has elapsed. only applicable if TimeoutSeconds is > 0, each argument is a separate string
2024-04-18 01:12:01 +00:00
}
// LoadConfiguration opens and parses the configuration file into a HypdConfiguration struct
// If a configFilePath is not specified, it will search in common locations
func LoadConfiguration ( configFilePath string ) ( * HypdConfiguration , error ) {
if configFilePath == "" {
commonLocations := [ ] string { "hypdconfig.json" ,
2024-04-18 01:41:24 +00:00
"~/.hypdconfig.json" ,
2024-04-18 01:12:01 +00:00
"~/.config/hyp/hypdConfig.json" ,
"/etc/hyp/hypdConfig.json" ,
"/usr/local/etc/hyp/hypdConfig.json" ,
}
for _ , loc := range commonLocations {
if _ , err := os . Stat ( loc ) ; err == nil {
configFilePath = loc
break
}
}
}
// if it's still not found after checking common locations, load default config
if configFilePath == "" {
2024-04-18 01:41:24 +00:00
fmt . Println ( "no configuration file found. You can generate one with ./hypd generate defaultconfig | tee hypdconfig.json" )
2024-04-18 01:12:01 +00:00
return DefaultConfig ( ) , nil
}
// Otherwise if a config is specified, try to load it and error if it fails.
// I think it's better to error here if a config was intended and failed
// rather than failing back to default
b , err := os . ReadFile ( configFilePath )
if err != nil {
return nil , fmt . Errorf ( "failed to read config file '%s': %w" , configFilePath , err )
}
2024-04-18 01:41:24 +00:00
hypdConfiguration := & HypdConfiguration { }
2024-04-18 01:12:01 +00:00
err = json . Unmarshal ( b , hypdConfiguration )
if err != nil {
return nil , fmt . Errorf ( "failed to unmarshal config file json to HypdConfiguration (is the config file malformed?): %w" , err )
}
2024-04-18 01:41:24 +00:00
return hypdConfiguration , nil
2024-04-18 01:12:01 +00:00
}
func DefaultConfig ( ) * HypdConfiguration {
2024-04-21 01:25:15 +00:00
var ifaceString string
iface , err := getDefaultNIC ( )
if err == nil {
ifaceString = iface . Name
} else {
ifaceString = "enp0s3" // fallback to fixed value
}
2024-04-18 01:12:01 +00:00
return & HypdConfiguration {
2024-04-21 01:25:15 +00:00
NetworkInterface : ifaceString ,
2024-04-18 01:12:01 +00:00
PreSharedKeyDirectory : "./secrets/" ,
SuccessAction : "iptables -A INPUT -p tcp -s %s --dport 22 -j ACCEPT" ,
TimeoutSeconds : 1440 ,
TimeoutAction : "iptables -D INPUT -p tcp -s %s --dport 22 -j ACCEPT" ,
}
}