From aba0f17953c9947bb51e78ed581f4e66b7012518 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Thu, 16 May 2024 12:48:22 +0200 Subject: 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. --- cmd/silentct-mac/examples.help2man | 6 ++ cmd/silentct-mac/main.go | 121 +++++++++++++++++++++++++++++++++++++ cmd/silentct-mac/name.help2man | 2 + cmd/silentct-mac/see-also.help2man | 2 + 4 files changed, 131 insertions(+) create mode 100644 cmd/silentct-mac/examples.help2man create mode 100644 cmd/silentct-mac/main.go create mode 100644 cmd/silentct-mac/name.help2man create mode 100644 cmd/silentct-mac/see-also.help2man (limited to 'cmd/silentct-mac') 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) -- cgit v1.2.3