diff --git a/cmd/certspotter/main.go b/cmd/certspotter/main.go index d873cdd..9730789 100644 --- a/cmd/certspotter/main.go +++ b/cmd/certspotter/main.go @@ -10,6 +10,7 @@ package main import ( + "bufio" "context" "errors" "flag" @@ -102,6 +103,9 @@ func defaultWatchListPathIfExists() string { func defaultScriptDir() string { return filepath.Join(defaultConfigDir(), "hooks.d") } +func defaultEmailFile() string { + return filepath.Join(defaultConfigDir(), "email_recipients") +} func simplifyError(err error) error { var pathErr *fs.PathError @@ -121,6 +125,25 @@ func readWatchListFile(filename string) (monitor.WatchList, error) { return monitor.ReadWatchList(file) } +func readEmailFile(filename string) ([]string, error) { + file, err := os.Open(filename) + if err != nil { + return nil, simplifyError(err) + } + defer file.Close() + + var emails []string + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + if line == "" { + continue + } + emails = append(emails, line) + } + return emails, err +} + func appendFunc(slice *[]string) func(string) error { return func(value string) error { *slice = append(*slice, value) @@ -183,9 +206,19 @@ func main() { HealthCheckInterval: flags.healthcheck, } - if len(config.Email) == 0 && config.Script == "" && !fileExists(config.ScriptDir) && config.Stdout == false { + emailFileExists := false + if emailRecipients, err := readEmailFile(defaultEmailFile()); err == nil { + emailFileExists = true + config.Email = append(config.Email, emailRecipients...) + } else if !errors.Is(err, fs.ErrNotExist) { + fmt.Fprintf(os.Stderr, "%s: error reading email recipients file %q: %s\n", programName, defaultEmailFile(), err) + os.Exit(1) + } + + if len(config.Email) == 0 && !emailFileExists && config.Script == "" && !fileExists(config.ScriptDir) && config.Stdout == false { fmt.Fprintf(os.Stderr, "%s: no notification methods were specified\n", programName) fmt.Fprintf(os.Stderr, "Please specify at least one of the following notification methods:\n") + fmt.Fprintf(os.Stderr, " - Place one or more email addresses in %s (one address per line)\n", defaultEmailFile()) fmt.Fprintf(os.Stderr, " - Place one or more executable scripts in the %s directory\n", config.ScriptDir) fmt.Fprintf(os.Stderr, " - Specify an email address using the -email flag\n") fmt.Fprintf(os.Stderr, " - Specify the path to an executable script using the -script flag\n")