diff options
author | Rasmus Dahlberg <rgdd@glasklarteknik.se> | 2024-05-16 12:48:22 +0200 |
---|---|---|
committer | Rasmus Dahlberg <rgdd@glasklarteknik.se> | 2024-05-16 17:26:38 +0200 |
commit | aba0f17953c9947bb51e78ed581f4e66b7012518 (patch) | |
tree | 6fbbbfe369224ca17088e429e49082f6ce9d5f5a /cmd/silentct-mac | |
parent | 6567c8f4ec3eefb855c6ef630a53b0fb8d8bf1e9 (diff) |
Add man pages and installer Makefile
Includes renaming of the tools, part one of trying to simplify
terminology and letting go of "node" and "moon". Improving the
terminology was suggested by Martin H a while back, thank you.
Diffstat (limited to 'cmd/silentct-mac')
-rw-r--r-- | cmd/silentct-mac/examples.help2man | 6 | ||||
-rw-r--r-- | cmd/silentct-mac/main.go | 121 | ||||
-rw-r--r-- | cmd/silentct-mac/name.help2man | 2 | ||||
-rw-r--r-- | cmd/silentct-mac/see-also.help2man | 2 |
4 files changed, 131 insertions, 0 deletions
diff --git a/cmd/silentct-mac/examples.help2man b/cmd/silentct-mac/examples.help2man new file mode 100644 index 0000000..f7bbff5 --- /dev/null +++ b/cmd/silentct-mac/examples.help2man @@ -0,0 +1,6 @@ +[EXAMPLES] +Allowlist the current certificate in a Let's Encrypt deployment: + +.B $ silentct-mac -n example.org -s sikritpassword -o /var/www/example.org/silent-ct/allowlist /etc/letsencrypt/live/example.org/fullchain.pem + +You may run the above as part of your crontab or certbot renewal configuration. diff --git a/cmd/silentct-mac/main.go b/cmd/silentct-mac/main.go new file mode 100644 index 0000000..2add812 --- /dev/null +++ b/cmd/silentct-mac/main.go @@ -0,0 +1,121 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "os" + "strings" + + "rgdd.se/silent-ct/internal/flagopt" + "rgdd.se/silent-ct/internal/ioutil" + "rgdd.se/silent-ct/internal/logger" + "rgdd.se/silent-ct/pkg/crtutil" + "rgdd.se/silent-ct/pkg/policy" + "rgdd.se/silent-ct/pkg/submission" +) + +const usage = ` +silentct-mac is a utility that helps allowlist legitimately issued certificates +while monitoring Certificate Transparency logs. One or more certificate chains +are bundled with a message authentication code, such that the silentct-mon tool +can fetch them over an insecure channel or from untrusted intermediary storage. + +Usage: silentct-mac [Options] -n NAME -s SECRET CRT-FILE [CRT-FILE ...] + +Options: + -n, --name Name of the system that allowlists certificates + -o, --output Filename to write allowlisted certificates to (default: stdout) + -s, --secret Shared secret between the allowlisting system and its monitor + -v, --verbosity Leveled logging output (default: NOTICE) +` + +type config struct { + // Options + name string + output string + secret string + verbosity string + + // Extracted + log *logger.Logger + files []string +} + +func configure(cmd string, args []string) (cfg config, err error) { + fs := flag.NewFlagSet(cmd, flag.ContinueOnError) + fs.Usage = func() {} + flagopt.StringOpt(fs, &cfg.name, "name", "n", "") + flagopt.StringOpt(fs, &cfg.output, "output", "o", "") + flagopt.StringOpt(fs, &cfg.secret, "secret", "s", "") + flagopt.StringOpt(fs, &cfg.verbosity, "verbosity", "v", logger.LevelNotice.String()) + if err = fs.Parse(args); err != nil { + return cfg, err + } + + // Options + if cfg.name == "" { + return cfg, fmt.Errorf("node name is required") + } + if cfg.secret == "" { + return cfg, fmt.Errorf("node secret is required") + } + lv, err := logger.NewLevel(cfg.verbosity) + if err != nil { + return cfg, fmt.Errorf("invalid verbosity: %v", err) + } + cfg.log = logger.New(logger.Config{Level: lv, File: os.Stderr}) + + // Arguments + cfg.files = fs.Args() + if len(cfg.files) == 0 { + return cfg, fmt.Errorf("at least one certificate chain file is required") + } + + return cfg, err +} + +func main() { + cfg, err := configure(os.Args[0], os.Args[1:]) + if err != nil { + if errors.Is(err, flag.ErrHelp) { + fmt.Fprintf(os.Stdout, "%s", usage[1:]) + os.Exit(0) + } + if !strings.Contains(err.Error(), "flag provided but not defined") { + fmt.Fprintf(os.Stdout, "%v\n", err) + } + os.Exit(1) + } + + var chains [][]byte + for i, path := range cfg.files { + b, err := ioutil.ReadData(path) + if err != nil { + cfg.log.Dief("file %d: %v\n", i, err) + } + if _, err := crtutil.CertificateChainFromPEM(b); err != nil { + cfg.log.Dief("file %d: %v\n", i, err) + } + + chains = append(chains, b) + } + + node, err := policy.NewNode(cfg.name, cfg.secret, "http://www.example.org/unused", nil) + if err != nil { + cfg.log.Dief("api: %v\n", err) + } + s, err := submission.New(node, chains) + if err != nil { + cfg.log.Dief("api: %v\n", err) + } + + fp := os.Stdout + if cfg.output != "" { + if fp, err = os.OpenFile(cfg.output, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644); err != nil { + cfg.log.Dief("output: %v\n", err) + } + } + + fmt.Fprintf(fp, "%s", string(s)) +} diff --git a/cmd/silentct-mac/name.help2man b/cmd/silentct-mac/name.help2man new file mode 100644 index 0000000..d7f6a28 --- /dev/null +++ b/cmd/silentct-mac/name.help2man @@ -0,0 +1,2 @@ +[NAME] +silentct-mac - allowlist certificates with message authentication codes diff --git a/cmd/silentct-mac/see-also.help2man b/cmd/silentct-mac/see-also.help2man new file mode 100644 index 0000000..02987dc --- /dev/null +++ b/cmd/silentct-mac/see-also.help2man @@ -0,0 +1,2 @@ +[SEE ALSO] +.BR silentct-mon (1) |