add support for multiple secrets (independent agents) on the knock daemon
Some checks failed
continuous-integration/drone/push Build is failing

This allows you to generate more than one pre-shared secret on the knock daemon so that you can distribute the secret and control revocation at a more granular level.  Each additional secret creates one more concurrent authentic knock sequence.
This commit is contained in:
2024-04-19 22:04:00 -06:00
parent 334407e309
commit 2951c1f684
5 changed files with 69 additions and 25 deletions

View File

@ -12,7 +12,6 @@ type HypdConfiguration struct {
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
}
// LoadConfiguration opens and parses the configuration file into a HypdConfiguration struct

View File

@ -0,0 +1,49 @@
package configuration
import (
"encoding/base32"
"fmt"
"io/fs"
"os"
"path/filepath"
)
var secrets [][]byte
// LoadSecrets processes all files within the specified directory and attempts to
// convert the file contents to secrets to by used by hypd
func LoadSecrets(preSharedKeyDirectory string) ([][]byte, error) {
secrets = make([][]byte, 0)
err := filepath.Walk(preSharedKeyDirectory, processSecretFile)
if err != nil {
return nil, fmt.Errorf("failed to walk directory '%s': %w", preSharedKeyDirectory, err)
}
return secrets, nil
}
// processSecretFile is called against each file in the preSharedKeyDirectory
// It reads each file and attemts to base32 decode their contents
func processSecretFile(path string, info fs.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("failed to process file '%s': %w", path, err)
}
if info.IsDir() {
return nil
}
secretBytes, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read file '%s': %w", path, err)
}
decodedSecret, err := base32.StdEncoding.DecodeString(string(secretBytes))
if err != nil {
return fmt.Errorf("failed to base32 decode secret '%s': %w", path, err)
}
secrets = append(secrets, decodedSecret)
return nil
}