Moving to OpenPrivacy Bine / Adding GetPID to ACN
the build was successful Details

This commit is contained in:
Sarah Jamie Lewis 2020-10-15 15:35:41 -07:00
parent 604237ea34
commit 0b0f65017a
9 changed files with 102 additions and 81 deletions

3
acn.go
View File

@ -52,5 +52,8 @@ type ACN interface {
// Listen takes a private key and a port and returns a ListenService for it
Listen(identity PrivateKey, port int) (ListenService, error)
// Get PID
GetPID() (int, error)
Close()
}

9
go.mod
View File

@ -3,12 +3,7 @@ module git.openprivacy.ca/openprivacy/connectivity
go 1.13
require (
git.openprivacy.ca/openprivacy/bine v0.0.3
git.openprivacy.ca/openprivacy/log v1.0.0
github.com/client9/misspell v0.3.4 // indirect
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf // indirect
github.com/stretchr/testify v1.3.0 // indirect
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d // indirect
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee
)

49
go.sum
View File

@ -1,43 +1,32 @@
git.openprivacy.ca/openprivacy/bine v0.0.2 h1:2uJyxOYfcYvpQAuRt5XWc81ZXrHuubdFskNOQjksEgc=
git.openprivacy.ca/openprivacy/bine v0.0.2/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU=
git.openprivacy.ca/openprivacy/bine v0.0.3 h1:PSHUmNqaW7BZUX8n2eTDeNbjsuRe+t5Ae0Og+P+jDM0=
git.openprivacy.ca/openprivacy/bine v0.0.3/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU=
git.openprivacy.ca/openprivacy/log v1.0.0 h1:Rvqm1weUdR4AOnJ79b1upHCc9vC/QF1rhSD2Um7sr1Y=
git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw=
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf h1:vc7Dmrk4JwS0ZPS6WZvWlwDflgDTA26jItmbSj83nug=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w=
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d h1:V1BGE5ZHrUIYZYNEm0i7jrPwSo3ks0HSn1TrartSqME=
golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -43,6 +43,10 @@ func (lp *localProvider) SetStatusCallback(callback func(int, string)) {
// nop
}
func (lp *localProvider) GetPID() (int, error) {
return 0, nil
}
// WaitTillBootstrapped Blocks until underlying network is bootstrapped
func (lp *localProvider) WaitTillBootstrapped() {
}

View File

@ -7,17 +7,19 @@ import (
"os"
"path"
"testing"
"time"
)
func TestLaunchTor(t *testing.T) {
log.SetLevel(log.LevelDebug)
rand.Seed(int64(time.Now().Nanosecond()))
controlPort := rand.Intn(1000) + 9052
password := "examplehashedpassword"
// Create the tor data directory if it doesn't already exist..
os.MkdirAll("../tmp/data/tor", 0700)
err := tor.NewTorrc().WithHashedPassword(password).WithControlPort(controlPort).Build("../tmp/data/tor/torrc")
err := tor.NewTorrc().WithControlPort(controlPort).WithHashedPassword(password).Build("../tmp/data/tor/torrc")
if err != nil {
t.Fatalf("failed to create torrc file: %v", err)
@ -29,8 +31,14 @@ func TestLaunchTor(t *testing.T) {
acn, err := tor.NewTorACNWithAuth(path.Clean(wd+"/../tmp/data"), path.Clean(wd+"/../tmp/tor"), controlPort, tor.HashedPasswordAuthenticator{Password: password})
if err != nil {
t.Fatalf("tor failed to start: %v", err)
} else {
acn.WaitTillBootstrapped()
if pid, err := acn.GetPID(); err == nil {
t.Logf("tor pid: %v", pid)
} else {
t.Fatalf("error fetching pid: %v", err)
}
t.Log("we have bootstrapped!")
acn.Close()
}
acn.WaitTillBootstrapped()
t.Log("we have bootstrapped!")
acn.Close()
}

4
testing/tor/torrc Normal file
View File

@ -0,0 +1,4 @@
SOCKSPort 9050
ControlPort 9051
# "examplehashedpassword" - used for testing
HashedControlPassword 16:C15305F97789414B601259E3EC5E76B8E55FC56A9F562B713F3D2BA257

View File

@ -4,12 +4,12 @@ import (
"context"
"errors"
"fmt"
"git.openprivacy.ca/openprivacy/bine/control"
"git.openprivacy.ca/openprivacy/bine/process"
"git.openprivacy.ca/openprivacy/bine/tor"
bineed255192 "git.openprivacy.ca/openprivacy/bine/torutil/ed25519"
"git.openprivacy.ca/openprivacy/connectivity"
"git.openprivacy.ca/openprivacy/log"
"github.com/cretz/bine/control"
"github.com/cretz/bine/process"
"github.com/cretz/bine/tor"
bineed255192 "github.com/cretz/bine/torutil/ed25519"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/sha3"
"net"
@ -65,7 +65,7 @@ type torProvider struct {
childListeners map[string]*onionListenService
statusCallback func(int, string)
lastRestartTime time.Time
authenticator Authenticator
authenticator tor.Authenticator
}
func (ols *onionListenService) AddressFull() string {
@ -240,10 +240,10 @@ func (tp *torProvider) callStatusCallback(prog int, status string) {
}
// NewTorACNWithAuth creates/starts a Tor ACN and returns a usable ACN object
func NewTorACNWithAuth(appDirectory string, bundledTorPath string, controlPort int, authenticator Authenticator) (connectivity.ACN, error) {
func NewTorACNWithAuth(appDirectory string, bundledTorPath string, controlPort int, authenticator tor.Authenticator) (connectivity.ACN, error) {
tp, err := startTor(appDirectory, bundledTorPath, controlPort, authenticator)
if err == nil {
tp.dialer, err = tp.t.Dialer(nil, &tor.DialConf{})
tp.dialer, err = tp.t.Dialer(nil, &tor.DialConf{Authenticator: authenticator})
if err == nil {
go tp.monitorRestart()
}
@ -267,29 +267,39 @@ func newHideCmd(exePath string) process.Creator {
})
}
func startTor(appDirectory string, bundledTorPath string, controlPort int, authenticator Authenticator) (*torProvider, error) {
dataDir := path.Join(appDirectory, "tor")
os.MkdirAll(dataDir, 0700)
tp := &torProvider{authenticator: authenticator, controlPort: controlPort, appDirectory: appDirectory, bundeledTorPath: bundledTorPath, childListeners: make(map[string]*onionListenService), breakChan: make(chan bool), statusCallback: nil, lastRestartTime: time.Now().Add(-restartCooldown)}
func (tp *torProvider) checkVersion() error {
// attempt connect to system tor
log.Debugf("dialing system tor control port\n")
log.Debugf("dialing system tor control port")
controlport, err := dialControlPort(tp.controlPort)
if err == nil {
err := authenticator.Authenticate(controlport)
defer controlport.Close()
err := tp.authenticator.Authenticate(controlport)
if err == nil {
log.Debugln("connected to control port")
pinfo, err := controlport.ProtocolInfo()
if err == nil && minTorVersionReqs(pinfo.TorVersion) {
log.Debugln("OK version " + pinfo.TorVersion)
tp.t = createFromExisting(controlport, dataDir)
return tp, nil
return nil
}
controlport.Close()
}
}
log.Debugf("launching system tor\n")
return err
}
func startTor(appDirectory string, bundledTorPath string, controlPort int, authenticator tor.Authenticator) (*torProvider, error) {
dataDir := path.Join(appDirectory, "tor")
os.MkdirAll(dataDir, 0700)
tp := &torProvider{authenticator: authenticator, controlPort: controlPort, appDirectory: appDirectory, bundeledTorPath: bundledTorPath, childListeners: make(map[string]*onionListenService), breakChan: make(chan bool), statusCallback: nil, lastRestartTime: time.Now().Add(-restartCooldown)}
log.Debugf("launching system tor")
if err := tp.checkVersion(); err == nil {
controlport, err := dialControlPort(tp.controlPort)
if err == nil {
log.Debugf("creating tor handler fom system tor")
tp.t = createFromExisting(controlport, dataDir)
}
return tp, nil
}
// check if the torrc file is present where expected
if _, err := os.Stat(path.Join(dataDir, "torrc")); os.IsNotExist(err) {
@ -300,26 +310,34 @@ func startTor(appDirectory string, bundledTorPath string, controlPort int, authe
// if not, try running system tor
if checkCmdlineTorVersion("tor") {
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, TorrcFile: path.Join(dataDir, "torrc"), DebugWriter: nil, ProcessCreator: newHideCmd("tor")})
t, err := tor.Start(nil, &tor.StartConf{ControlPort: tp.controlPort, UseEmbeddedControlConn: false, DisableEagerAuth: true, EnableNetwork: true, DataDir: dataDir, TorrcFile: path.Join(dataDir, "torrc"), DebugWriter: nil, ProcessCreator: newHideCmd("tor")})
if err == nil {
tp.t = t
return tp, nil
}
log.Debugf("Error connecting to self-run system tor: %v\n", err)
}
log.Debugf("launching bundled tor\n")
// try running bundledTor
if bundledTorPath != "" && checkCmdlineTorVersion(bundledTorPath) {
log.Debugln("using bundled tor '" + bundledTorPath + "'")
t, err := tor.Start(nil, &tor.StartConf{EnableNetwork: true, DataDir: dataDir, TorrcFile: path.Join(dataDir, "torrc"), ExePath: bundledTorPath, DebugWriter: nil, ProcessCreator: newHideCmd(bundledTorPath)})
} else if bundledTorPath != "" && checkCmdlineTorVersion(bundledTorPath) {
log.Debugln("attempting using bundled tor '" + bundledTorPath + "'")
t, err := tor.Start(nil, &tor.StartConf{ControlPort: tp.controlPort, DisableCookieAuth: true, UseEmbeddedControlConn: false, DisableEagerAuth: true, EnableNetwork: true, DataDir: dataDir, TorrcFile: path.Join(dataDir, "torrc"), ExePath: bundledTorPath, DebugWriter: nil, ProcessCreator: newHideCmd(bundledTorPath)})
if err != nil {
log.Debugf("Error running bundled tor: %v\n", err)
log.Debugf("Error running bundled tor %v\n", err)
}
tp.t = t
return tp, err
}
return nil, errors.New("Could not connect to or start Tor that met requirments (min Tor version 0.3.5.x)")
err := tp.checkVersion()
if err == nil {
return tp, nil
}
return nil, fmt.Errorf("could not connect to or start Tor that met requirments (min Tor version 0.3.5.x): %v", err)
}
func (tp *torProvider) GetPID() (int, error) {
val, err := tp.t.Control.GetInfo("process/pid")
if err == nil {
return strconv.Atoi(val[0].Val)
}
return 0, err
}
func (tp *torProvider) unregisterListener(id string) {
@ -398,8 +416,6 @@ func createFromExisting(controlport *control.Conn, datadir string) *tor.Tor {
}
t.Control.DebugWriter = t.DebugWriter
t.EnableNetwork(nil, true)
return t
}

View File

@ -2,6 +2,8 @@ package tor
import (
"fmt"
"git.openprivacy.ca/openprivacy/log"
"path"
"testing"
)
@ -14,7 +16,10 @@ func getStatusCallback(progChan chan int) func(int, string) {
func TestTorProvider(t *testing.T) {
progChan := make(chan int)
acn, err := NewTorACNWithAuth(".", "", 9051, HashedPasswordAuthenticator{"examplehashedpassword"})
log.SetLevel(log.LevelDebug)
torpath := path.Join("..", "tmp/tor")
log.Debugf("setting tor path %v", torpath)
acn, err := NewTorACNWithAuth(path.Join("../testing/"), torpath, 9051, HashedPasswordAuthenticator{"examplehashedpassword"})
if err != nil {
t.Error(err)
return
@ -24,6 +29,7 @@ func TestTorProvider(t *testing.T) {
progress := 0
for progress < 100 {
progress = <-progChan
t.Logf("progress: %v", progress)
}
acn.Close()

View File

@ -3,7 +3,8 @@ package tor
import (
"encoding/base32"
"errors"
"github.com/cretz/bine/control"
"git.openprivacy.ca/openprivacy/bine/control"
"git.openprivacy.ca/openprivacy/bine/tor"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/sha3"
"strings"
@ -52,11 +53,6 @@ func IsValidHostname(address string) bool {
return false
}
// Authenticator provides a facade over various Tor control port authentication methods.
type Authenticator interface {
Authenticate(controlport *control.Conn) error
}
// HashedPasswordAuthenticator authenticates to a Tor control port using a hashed password.
// Note: This method is vulnerable to replay attacks by the host system (but so is cookie auth)
type HashedPasswordAuthenticator struct {
@ -69,7 +65,7 @@ func (h HashedPasswordAuthenticator) Authenticate(controlport *control.Conn) err
}
// NewHashedPasswordAuthenticator creates a new hashed password authenticator
func NewHashedPasswordAuthenticator(password string) Authenticator {
func NewHashedPasswordAuthenticator(password string) tor.Authenticator {
return HashedPasswordAuthenticator{Password: password}
}