forked from cwtch.im/cwtch
Merge branch 'tor' of cwtch.im/cwtch into master
This commit is contained in:
commit
7cf6bbcecc
43
app/app.go
43
app/app.go
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue