Testing Tor Manager + Some bug fixes

This commit is contained in:
Sarah Jamie Lewis 2018-07-01 11:43:05 -07:00
parent 44384d1cec
commit f435de4b71
5 changed files with 102 additions and 58 deletions

View File

@ -3,7 +3,11 @@ package app
import (
"cwtch.im/cwtch/connectivity/tor"
"cwtch.im/cwtch/peer"
"fmt"
"log"
"os"
"os/user"
"path"
)
// Application is a facade over a cwtchPeer that provides some wrapping logic.
@ -19,11 +23,10 @@ func (app *Application) NewProfile(name string, filename string, password string
err := profile.Save(filename)
if err == nil {
_, err := tor.NewTorManager(9050, 9051)
err := app.startTor()
if err != nil {
return err
}
go func() {
err := app.Peer.Listen()
if err != nil {
@ -34,6 +37,38 @@ func (app *Application) NewProfile(name string, filename string, password string
return err
}
func (app *Application) startTor() error {
// Creating a local cwtch tor server config for the user
usr, err := user.Current()
if err != nil {
return err
}
// creating /home/<usr>/.cwtch/torrc file
// SOCKSPort socksPort
// ControlPort controlPort
torrc := path.Join(usr.HomeDir, ".cwtch", "torrc")
if _, err := os.Stat(torrc); os.IsNotExist(err) {
os.MkdirAll(path.Join(usr.HomeDir, ".cwtch"), 0700)
file, err := os.Create(torrc)
if err != nil {
return err
}
fmt.Fprintf(file, "SOCKSPort %d\nControlPort %d\n", 9050, 9051)
file.Close()
}
tm, err := tor.NewTorManager(9050, 9051, torrc)
if err != nil {
return err
}
app.TorManager = tm
return nil
}
// SetProfile loads an existing profile from the given filename.
func (app *Application) SetProfile(filename string, password string) error {
profile, err := peer.LoadCwtchPeer(filename, password)
@ -43,12 +78,10 @@ func (app *Application) SetProfile(filename string, password string) error {
app.Peer = profile
if err == nil {
tm, err := tor.NewTorManager(9050, 9051)
err := app.startTor()
if err != nil {
return err
}
app.TorManager = tm
go func() {
err := app.Peer.Listen()
if err != nil {

View File

@ -8,15 +8,12 @@ import (
"net"
"net/http"
"net/url"
"os"
"os/exec"
"os/user"
"path"
"strings"
"time"
)
// Manager checks connectivity of the Tor process used to support Cwtch/
// Manager checks connectivity of the Tor process used to support Cwtch
type Manager struct {
socksPort int
controlPort int
@ -24,44 +21,28 @@ type Manager struct {
}
// NewTorManager Instantiates a new connection manager, returns non-nil error if it fails to connect to a tor daemon on the given ports.
func NewTorManager(socksPort int, controlPort int) (*Manager, error) {
func NewTorManager(socksPort int, controlPort int, torrc string) (*Manager, error) {
torManager := new(Manager)
torManager.socksPort = socksPort
torManager.controlPort = controlPort
err := torManager.TestConnection()
if err != nil {
usr, err := user.Current()
if err != nil {
return nil, err
}
torrc := path.Join(usr.HomeDir, ".cwtch", "torrc")
if _, err := os.Stat(torrc); os.IsNotExist(err) {
os.MkdirAll(path.Join(usr.HomeDir, ".cwtch"), 0700)
file, err := os.Create(torrc)
if err != nil {
return nil, err
}
fmt.Fprintf(file, "SOCKSPort %d\nControlPort %d\n", socksPort, controlPort)
file.Close()
}
cmd := exec.Command("tor", "-f", torrc)
err = cmd.Start()
if err != nil {
return nil, err
}
fmt.Printf("\nWaiting to connect to Tor Proxy...\n")
time.Sleep(time.Second * 5)
torManager.process = cmd
err = torManager.TestConnection()
return torManager, err
if err == nil {
log.Printf("using existing tor proxy")
return torManager, nil
}
// try to start tor
cmd := exec.Command("tor", "-f", torrc)
log.Printf("starting local tor proxy")
err = cmd.Start()
if err != nil {
log.Printf("starting tor failed %v", err)
return nil, err
}
time.Sleep(time.Second * 5)
torManager.process = cmd
err = torManager.TestConnection()
return torManager, err
}

View File

@ -0,0 +1,27 @@
package tor
import (
"fmt"
"os"
"testing"
)
func TestTorManager(t *testing.T) {
os.Remove("/tmp/torrc")
file, _ := os.Create("/tmp/torrc")
fmt.Fprintf(file, "SOCKSPort %d\nControlPort %d\nDataDirectory /tmp/tor\n", 10050, 10051)
file.Close()
tm, err := NewTorManager(10050, 10051, "/tmp/torrc")
if err != nil {
t.Errorf("creating a new tor manager failed: %v", err)
} else {
tm2, err := NewTorManager(10050, 10051, "/tmp/torrc")
if err != nil {
t.Errorf("creating a new tor manager failed: %v", err)
}
tm2.Shutdown() // should not noop
}
tm.Shutdown()
}

View File

@ -170,26 +170,28 @@ func (cp *cwtchPeer) Save(profilefile string) error {
// LoadCwtchPeer loads an existing cwtchPeer from a file.
func LoadCwtchPeer(profilefile string, password string) (CwtchPeerInterface, error) {
encryptedbytes, _ := ioutil.ReadFile(profilefile)
encryptedbytes, err := ioutil.ReadFile(profilefile)
var dkr [32]byte
var salty [128]byte
//Separate the salt from the encrypted bytes, then generate the derived key
salt, encryptedbytes := encryptedbytes[0:128], encryptedbytes[128:]
dk := pbkdf2.Key([]byte(password), salt, 4096, 32, sha3.New512)
//cast to arrays
copy(dkr[:], dk)
copy(salty[:], salt)
cp, err := decryptProfile(encryptedbytes, dkr)
if err == nil {
cp.setup()
cp.profilefile = profilefile
cp.key = dkr
cp.salt = salty
return cp, nil
var dkr [32]byte
var salty [128]byte
//Separate the salt from the encrypted bytes, then generate the derived key
salt, encryptedbytes := encryptedbytes[0:128], encryptedbytes[128:]
dk := pbkdf2.Key([]byte(password), salt, 4096, 32, sha3.New512)
//cast to arrays
copy(dkr[:], dk)
copy(salty[:], salt)
cp, err := decryptProfile(encryptedbytes, dkr)
if err == nil {
cp.setup()
cp.profilefile = profilefile
cp.key = dkr
cp.salt = salty
return cp, nil
}
}
return nil, err
}

View File

@ -16,6 +16,7 @@ go test ${1} -coverprofile=server.listen.cover.out -v ./server/listen
go test ${1} -coverprofile=server.send.cover.out -v ./server/send
go test ${1} -coverprofile=server.metrics.cover.out -v ./server/metrics
go test ${1} -coverprofile=server.cover.out -v ./server
go test ${1} -coverprofile=tor.cover.out -v ./connectivity/tor
echo "mode: set" > coverage.out && cat *.cover.out | grep -v mode: | sort -r | \
awk '{if($1 != last) {print $0;last=$1}}' >> coverage.out
rm -rf *.cover.out