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 (
|
import (
|
||||||
"cwtch.im/cwtch/connectivity/tor"
|
"cwtch.im/cwtch/connectivity/tor"
|
||||||
"cwtch.im/cwtch/peer"
|
"cwtch.im/cwtch/peer"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Application is a facade over a cwtchPeer that provides some wrapping logic.
|
// 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)
|
err := profile.Save(filename)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
_, err := tor.NewTorManager(9050, 9051)
|
err := app.startTor()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err := app.Peer.Listen()
|
err := app.Peer.Listen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -34,6 +37,38 @@ func (app *Application) NewProfile(name string, filename string, password string
|
||||||
return err
|
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.
|
// SetProfile loads an existing profile from the given filename.
|
||||||
func (app *Application) SetProfile(filename string, password string) error {
|
func (app *Application) SetProfile(filename string, password string) error {
|
||||||
profile, err := peer.LoadCwtchPeer(filename, password)
|
profile, err := peer.LoadCwtchPeer(filename, password)
|
||||||
|
@ -43,12 +78,10 @@ func (app *Application) SetProfile(filename string, password string) error {
|
||||||
app.Peer = profile
|
app.Peer = profile
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
tm, err := tor.NewTorManager(9050, 9051)
|
err := app.startTor()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
app.TorManager = tm
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err := app.Peer.Listen()
|
err := app.Peer.Listen()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -8,15 +8,12 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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 {
|
type Manager struct {
|
||||||
socksPort int
|
socksPort int
|
||||||
controlPort 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.
|
// 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 := new(Manager)
|
||||||
torManager.socksPort = socksPort
|
torManager.socksPort = socksPort
|
||||||
torManager.controlPort = controlPort
|
torManager.controlPort = controlPort
|
||||||
err := torManager.TestConnection()
|
err := torManager.TestConnection()
|
||||||
|
|
||||||
if err != nil {
|
if err == nil {
|
||||||
|
log.Printf("using existing tor proxy")
|
||||||
usr, err := user.Current()
|
return torManager, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
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.
|
// LoadCwtchPeer loads an existing cwtchPeer from a file.
|
||||||
func LoadCwtchPeer(profilefile string, password string) (CwtchPeerInterface, error) {
|
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 {
|
if err == nil {
|
||||||
cp.setup()
|
var dkr [32]byte
|
||||||
cp.profilefile = profilefile
|
var salty [128]byte
|
||||||
cp.key = dkr
|
|
||||||
cp.salt = salty
|
//Separate the salt from the encrypted bytes, then generate the derived key
|
||||||
return cp, nil
|
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
|
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.send.cover.out -v ./server/send
|
||||||
go test ${1} -coverprofile=server.metrics.cover.out -v ./server/metrics
|
go test ${1} -coverprofile=server.metrics.cover.out -v ./server/metrics
|
||||||
go test ${1} -coverprofile=server.cover.out -v ./server
|
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 | \
|
echo "mode: set" > coverage.out && cat *.cover.out | grep -v mode: | sort -r | \
|
||||||
awk '{if($1 != last) {print $0;last=$1}}' >> coverage.out
|
awk '{if($1 != last) {print $0;last=$1}}' >> coverage.out
|
||||||
rm -rf *.cover.out
|
rm -rf *.cover.out
|
||||||
|
|
Loading…
Reference in New Issue