1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
// Package main provides a utility named ct-sans.
//
// Install:
//
// go install rgdd.se/ct-sans@latest
//
// Usage:
//
// $ ct-sans -h
package main
import (
"flag"
"fmt"
"log"
"os"
"time"
"rgdd.se/ct-sans/internal/ctflag"
)
const usage = `ct-sans collects SANs in CT-logged certificates
Usage:
ct-sans snapshot [Options...]
Refresh log lists, signed tree heads, and timestamps
ct-sans collect [Options...]
Collect SANs with regards to the current snapshot
ct-sans assemble [Options...]
Assemble dataset from the collected data (requires GNU sort)
Help:
ct-sans [-h] [--help]
Snapshot options:
-d, --directory: The ct-sans working directory (Default: "data")
Collect options:
-d, --directory: The ct-sans working directory (Default: "data")
-w, --workers: Max number of parallel download workers per log (Default: 2).
-k, --batch-disk: Certificate batch size before persisting (Default: 256)
-q, --batch-req: Certificate batch size to use in request (Default: 128)
-a, --http-agent: HTTP agent to use in all request (Default: "rgdd.se/ct-sans")
-m, --metrics: How often to emit metrics to stderr (Default: 16s)
Asemble options:
-d, --directory: The ct-sans working directory (Default: "data")
-b, --buffer-size: Max memory to use in Gigabytes (Default: 1)
-t, --temp-dir: Temporary on-disk storage directory (Default: /tmp)
-p, --parallel: Number of CPUs to use (Default: 1)
`
type options struct {
// Common options
Directory string
// Collect options
WorkersPerLog uint64
PersistSize uint64
BatchSize uint64
HTTPAgent string
MetricsInterval time.Duration
// Assemble options
BufferSize uint64
TempDir string
Parallel uint64
// Constants
logDirectory string
archiveDirectory string
metadataFile string
metadataSignatureFile string
metadataTimestampFile string
sthFile string
sthsFile string
stateFile string
sansFile string
visitFile string
noticeFile string
}
func main() {
log.SetOutput(os.Stdout)
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
if ctflag.WantHelp(os.Args, 1) {
fmt.Fprintf(os.Stdout, usage)
os.Exit(1)
}
// Define command-line options
fs := ctflag.NewFlagSet()
opts := options{}
ctflag.String(&fs, &opts.Directory, "directory", "d", "data")
ctflag.Uint64(&fs, &opts.WorkersPerLog, "workers", "w", 2)
ctflag.Uint64(&fs, &opts.PersistSize, "batch-disk", "k", 256)
ctflag.Uint64(&fs, &opts.BatchSize, "batch-req", "q", 128)
ctflag.String(&fs, &opts.HTTPAgent, "http-agent", "a", "rgdd.se/ct-sans")
ctflag.Duration(&fs, &opts.MetricsInterval, "metrics", "m", 16*time.Second)
ctflag.Uint64(&fs, &opts.BufferSize, "buffer-size", "b", 1)
ctflag.String(&fs, &opts.TempDir, "temp-dir", "t", "/tmp")
ctflag.Uint64(&fs, &opts.Parallel, "parallel", "p", 1)
// Parse command-line options and hardcode additional values
if err := ctflag.Parse(fs, os.Args[2:]); err != nil {
if err == flag.ErrHelp {
fmt.Fprintf(os.Stdout, usage)
os.Exit(1)
}
fmt.Fprintf(os.Stdout, "error: %v\n\n", err)
os.Exit(1)
}
opts.logDirectory = opts.Directory + "/" + "logs"
opts.archiveDirectory = opts.Directory + "/" + "archive"
opts.metadataFile = "metadata.json"
opts.metadataSignatureFile = "metadata.sig"
opts.metadataTimestampFile = "metadata.timestamp"
opts.sthFile = "sth.json"
opts.sthsFile = "sths.json"
opts.stateFile = "th.json"
opts.sansFile = "sans.lst"
opts.visitFile = "visit.lst"
opts.noticeFile = "notice.txt"
// Hand-over to the respective subcommands
var err error
switch cmd := os.Args[1]; cmd {
case "snapshot":
err = snapshot(opts)
case "collect":
err = collect(opts)
case "assemble":
err = assemble(opts)
default:
fmt.Fprintf(os.Stdout, "ct-sans: unknown command %q\n\n", cmd)
os.Exit(1)
}
if err != nil {
fmt.Fprintf(os.Stdout, "ct-sans %s: error: %v\n", os.Args[1], err)
os.Exit(1)
}
}
|