diff --git a/hypd/configuration/configuration.go b/hypd/configuration/configuration.go index 38ce2db..3c50d36 100644 --- a/hypd/configuration/configuration.go +++ b/hypd/configuration/configuration.go @@ -7,11 +7,11 @@ import ( ) type HypdConfiguration struct { - NetworkInterface string `json:"networkInterface"` + NetworkInterface string `json:"networkInterface"` // The network interface that the eBPF program attaches to PreSharedKeyDirectory string `json:"preSharedKeyDirectory"` // hypd will load all *.secret files from this directory - SuccessAction string `json:"successAction"` // The action to take - 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 + 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 } diff --git a/hypd/server/packet.go b/hypd/server/packet.go index a8d2414..e85ed91 100644 --- a/hypd/server/packet.go +++ b/hypd/server/packet.go @@ -44,15 +44,17 @@ var ( clients map[uint32]*Client // Contains a map of clients, key is IPv4 address knockSequences []KnockSequence // We have 3 valid knock sequences at any time to account for clock skew sharedSecret string // base32 encoded shared secret used for totp + serverConfig *configuration.HypdConfiguration ) // PacketServer is the main function when operating in server mode // it sets up the pcap on the capture device and starts a goroutine // to rotate the knock sequence func PacketServer(config *configuration.HypdConfiguration) error { - iface, err := net.InterfaceByName(config.NetworkInterface) + serverConfig = config + iface, err := net.InterfaceByName(serverConfig.NetworkInterface) if err != nil { - log.Fatalf("lookup network iface %q: %v", config.NetworkInterface, err) + log.Fatalf("lookup network iface %q: %v", serverConfig.NetworkInterface, err) } secretBytes, err := os.ReadFile("hyp.secret") @@ -197,12 +199,15 @@ func rotateSequence() { } } -// TBD: Implement - this is a temporary routine to demonstrate an application +// handleSuccess is ran when a source IP successfully enters the authentic knock sequence +// the configured success action is ran func handleSuccess(srcip net.IP) { - fmt.Println("Success for ", srcip) - cmd := exec.Command("iptables", "-A", "INPUT", "-p", "tcp", "-s", fmt.Sprint(srcip), "--dport", "22", "-j", "ACCEPT") + fmt.Println("Successful knock from:", srcip) + // Don't care about command injection, the configuration file providing the command literally NEEDS to be trusted + // TBD: Use template / substitution instead of string formatting directive - allows for srcip token to be used multiple times + cmd := exec.Command("sh", "-c", fmt.Sprintf(serverConfig.SuccessAction, srcip)) err := cmd.Run() if err != nil { - log.Printf("failed to execute iptables command for '%s': %v", srcip, err) + log.Printf("failed to execute success action command for '%s': %v", srcip, err) } }