Skip to content
This repository has been archived by the owner on Oct 29, 2021. It is now read-only.

Commit

Permalink
btget: initial hacks to get everything working
Browse files Browse the repository at this point in the history
  • Loading branch information
philips committed May 4, 2020
1 parent 263f213 commit 269deb5
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 20 deletions.
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
private
public
dist/
production/secrets
btget.db
154 changes: 138 additions & 16 deletions btget/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,32 @@
package cmd

import (
"bytes"
"crypto/sha256"
"errors"
"database/sql"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"strings"

"github.com/cavaliercoder/grab"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/mod/sumdb/note"
_ "rsc.io/sqlite"

"github.com/cavaliercoder/grab"
"github.com/google/certificate-transparency-go/loglist"
"go.transparencylog.net/btget/sumdb"
)

var cfgFile string

var serverAddr string

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "btget [URL]",
Expand All @@ -57,6 +66,7 @@ func Execute() {
}

func init() {
serverAddr = "binary.transparencylog.net"
cobra.OnInitialize(initConfig)

// Here you will define your flags and configuration settings.
Expand Down Expand Up @@ -95,29 +105,107 @@ func initConfig() {
}
}

func validSCTs(valid, invalid int, cturl string, logs []loglist.Log) string {
var names []string
for _, l := range logs {
names = append(names, l.Description)
type clientCache struct {
sql *sql.DB
}

func NewClientCache() *clientCache {
client := &clientCache{}
// TODO: make filename configurable
sdb, err := sql.Open("sqlite3", "btget.db")
if err != nil {
log.Fatal(err)
}
if _, err := sdb.Exec(`create table if not exists kv (k primary key, v)`); err != nil {
log.Fatal(err)
}
client.sql = sdb
return client
}

func (c *clientCache) ReadRemote(path string) ([]byte, error) {
resp, err := http.Get("https://" + serverAddr + path)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("http get: %v", resp.Status)
}
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return data, nil
}

func (c *clientCache) ReadConfig(file string) (data []byte, err error) {
defer func() {
if err != nil {
err = fmt.Errorf("read config %s: %v", file, err)
}
}()

data, err = sqlRead(c.sql, "config:"+file)
if strings.HasSuffix(file, "/latest") && err == sql.ErrNoRows {
return nil, nil
}
return fmt.Sprintf("validated %d/%d SCTs in logs %q ", valid, (valid + invalid), strings.Join(names, ", "))
return data, err
}

func levelSCTs(valid, invalid int) (string, error) {
switch {
case valid != 0 && invalid == 0:
return "OK", nil
case valid == 0:
return "Error", errors.New("no valid SCTs")
default:
return "Warning", nil
func (c *clientCache) WriteConfig(file string, old, new []byte) error {
if old == nil {
return sqlWrite(c.sql, "config:"+file, new)
}
return sqlSwap(c.sql, "config:"+file, old, new)
}

func (c *clientCache) ReadCache(file string) ([]byte, error) {
return sqlRead(c.sql, "file:"+file)
}

func (c *clientCache) WriteCache(file string, data []byte) {
sqlWrite(c.sql, "file:"+file, data)
}

func (c *clientCache) Log(msg string) {
log.Print(msg)
}

func (c *clientCache) SecurityError(msg string) {
log.Fatal(msg)
}

func get(cmd *cobra.Command, args []string) {
durl := args[0]

u, err := url.Parse(durl)
if err != nil {
panic(err)
}
key := u.Host + u.Path

// Step 0: Initialize cache if needed
vkey := "sum.golang.org+033de0ae+Ac4zctda0e5eza+HJyk9SxEdh+s3Ux18htTTAD8OuAn8"
if _, err := note.NewVerifier(vkey); err != nil {
log.Fatalf("invalid verifier key: %v", err)
}
cache := NewClientCache()
_, err = cache.ReadConfig("key")
if err == nil {
if err := cache.WriteConfig("key", nil, []byte(vkey)); err != nil {
log.Fatal(err)
}
}

// Step 1: Download the tlog entry for the URL
client := sumdb.NewClient(cache)
log.Print("looking up key: ", key)
_, data, err := client.Lookup(key)
if err != nil {
log.Fatal(err)
}
os.Stdout.Write(data)

// create download request
req, err := grab.NewRequest("", durl)
Expand Down Expand Up @@ -163,3 +251,37 @@ func get(cmd *cobra.Command, args []string) {

fmt.Println("Download validated and saved to", resp.Filename)
}

func sqlRead(db *sql.DB, key string) ([]byte, error) {
var value []byte
err := db.QueryRow(`select v from kv where k = ?`, key).Scan(&value)
if err != nil {
return nil, err
}
return value, nil
}

func sqlWrite(db *sql.DB, key string, value []byte) error {
_, err := db.Exec(`insert or replace into kv (k, v) values (?, ?)`, key, value)
return err
}

func sqlSwap(db *sql.DB, key string, old, value []byte) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()

var txOld []byte
if err := tx.QueryRow(`select v from kv where k = ?`, key).Scan(&txOld); err != nil {
return err
}
if !bytes.Equal(txOld, old) {
return sumdb.ErrWriteConflict
}
if _, err := tx.Exec(`insert or replace into kv (k, v) values (?, ?)`, key, value); err != nil {
return err
}
return tx.Commit()
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.6.3
golang.org/x/mod v0.2.0
rsc.io/sqlite v1.0.0
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,16 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a h1:YX8ljsm6wXlHZO+aRz9Exqr0evNhKRNe5K/gi+zKh4U=
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -280,6 +284,7 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
Expand All @@ -303,6 +308,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -329,7 +335,10 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.6.0/go.mod h1:btoxGiFvQNVUZQ8W08zLtrVS08CNpINPEfxXxgJL1Q4=
Expand Down Expand Up @@ -371,4 +380,6 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34/go.mod h1:H6SUd1XjIs+qQCyskXg5OFSrilMRUkD8ePJpHKDPaeY=
rsc.io/sqlite v1.0.0 h1:zUGL/JDeFfblrma2rToXG+fUsGZe+CShUHI3KlUNwQc=
rsc.io/sqlite v1.0.0/go.mod h1:bRoHdqsJCgrcQDvBeCS454l4kLoFAQKHdwfwpoweIOo=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

0 comments on commit 269deb5

Please sign in to comment.