aboutsummaryrefslogtreecommitdiff
path: root/server/main.go
blob: 8f5ab4801e72aa7b15e0512777024c444e1b19a1 (plain)
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
// Package main provides an STFE server binary
package main

import (
	"flag"
	"strings"
	"time"

	"crypto/ed25519"
	"encoding/base64"
	"net/http"

	"github.com/golang/glog"
	"github.com/google/trillian"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/system-transparency/stfe"
	"github.com/system-transparency/stfe/namespace"
	"google.golang.org/grpc"
)

var (
	httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where stfe serves clients")
	rpcBackend   = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients")
	prefix       = flag.String("prefix", "st/v1", "a prefix that proceeds each endpoint path")
	trillianID   = flag.Int64("trillian_id", 5991359069696313945, "log identifier in the Trillian database")
	rpcDeadline  = flag.Duration("rpc_deadline", time.Second*10, "deadline for backend RPC requests")
	key          = flag.String("key", "8gzezwrU/2eTrO6tEYyLKsoqn5V54URvKIL9cTE7jUYUqXVX4neJvcBq/zpSAYPsZFG1woh0OGBzQbi9UP9MZw==", "base64-encoded Ed25519 signing key")
	namespaces   = flag.String("namespaces", "AAEgHOQFUkKNWpjYAhNKTyWCzahlI7RDtf5123kHD2LACj0=,AAEgLqrWb9JwQUTk/SwTNDdMH8aRmy3mbmhwEepO5WSgb+A=", "comma-separated list of trusted namespaces in base64 (default: testdata.Ed25519{Vk,Vk2})")
	maxRange     = flag.Int64("max_range", 2, "maximum number of entries that can be retrived in a single request")
)

func main() {
	flag.Parse()

	glog.Info("Dialling Trillian gRPC log server")
	dialOpts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithBlock(), grpc.WithTimeout(*rpcDeadline)}
	conn, err := grpc.Dial(*rpcBackend, dialOpts...)
	if err != nil {
		glog.Fatal(err)
	}
	client := trillian.NewTrillianLogClient(conn)

	glog.Info("Creating HTTP request multiplexer")
	mux := http.NewServeMux()
	http.Handle("/", mux)

	glog.Info("Adding prometheus handler on path: /metrics")
	http.Handle("/metrics", promhttp.Handler())

	glog.Infof("Creating namespace pool")
	var anchors []*namespace.Namespace
	for _, b64 := range strings.Split(*namespaces, ",") {
		b, err := base64.StdEncoding.DecodeString(b64)
		if err != nil {
			glog.Fatalf("invalid namespace: %s: %v", b64, err)
		}
		var namespace namespace.Namespace
		if err := namespace.Unmarshal(b); err != nil {
			glog.Fatalf("invalid namespace: %s: %v", b64, err)
		}
		anchors = append(anchors, &namespace)
	}
	pool, err := namespace.NewNamespacePool(anchors)
	if err != nil {
		glog.Fatalf("invalid namespace pool: %v", err)
	}

	glog.Infof("Creating log signer and identifier")
	sk, err := base64.StdEncoding.DecodeString(*key)
	if err != nil {
		glog.Fatalf("invalid signing key: %v", err)
	}
	signer := ed25519.PrivateKey(sk)
	logId, err := namespace.NewNamespaceEd25519V1([]byte(ed25519.PrivateKey(sk).Public().(ed25519.PublicKey)))
	if err != nil {
		glog.Fatalf("failed creating log id from secret key: %v", err)
	}

	glog.Infof("Initializing log parameters")
	lp, err := stfe.NewLogParameters(signer, logId, *trillianID, *prefix, pool, *maxRange)
	if err != nil {
		glog.Fatalf("failed setting up log parameters: %v", err)
	}

	i := stfe.NewInstance(lp, client, *rpcDeadline)
	for _, handler := range i.Handlers() {
		glog.Infof("adding handler: %s", handler.Path())
		mux.Handle(handler.Path(), handler)
	}
	glog.Infof("Configured: %s", i)

	glog.Infof("Serving on %v/%v", *httpEndpoint, *prefix)
	srv := http.Server{Addr: *httpEndpoint}
	err = srv.ListenAndServe()
	if err != http.ErrServerClosed {
		glog.Warningf("Server exited: %v", err)
	}

	glog.Flush()
}