From 1be58828fe7c2f1227c381522ac51c9e6d8de77c Mon Sep 17 00:00:00 2001 From: John Brooks Date: Sat, 5 Nov 2016 22:09:18 -0600 Subject: [PATCH] core: Remove hardcoded tor control address The default address will be set from the environment, or fall back to trying 127.0.0.1:9051. There is now an API to allow this to be overriden as well. --- core/network.go | 64 +++++++++++++++++++++++++++++++---------------- core/ricochet.go | 37 +++++++++++++++++++++------ core/rpcserver.go | 2 +- 3 files changed, 72 insertions(+), 31 deletions(-) diff --git a/core/network.go b/core/network.go index f6841ed..b1a962b 100644 --- a/core/network.go +++ b/core/network.go @@ -6,7 +6,6 @@ import ( "github.com/ricochet-im/ricochet-go/core/utils" "github.com/ricochet-im/ricochet-go/rpc" "github.com/yawning/bulb" - bulbutils "github.com/yawning/bulb/utils" "golang.org/x/net/context" "golang.org/x/net/proxy" "log" @@ -65,23 +64,45 @@ func CreateNetwork() *Network { } } -// Start connection to the tor control port at 'address', with the optional -// control password 'password'. This function blocks until the first connection -// attempt is finished. The first return value says whether the connection has -// been started; if true, the connection is up even if the first attempt failed. -// The second return value is the connection attempt error, or nil on success. -func (n *Network) Start(address, password string) (bool, error) { +func (n *Network) SetControlAddress(address string) error { + n.controlMutex.Lock() + defer n.controlMutex.Unlock() + if n.stoppedSignal != nil { + return errors.New("Network is already started") + } + + n.controlAddress = address + return nil +} + +func (n *Network) SetControlPassword(password string) error { + n.controlMutex.Lock() + defer n.controlMutex.Unlock() + if n.stoppedSignal != nil { + return errors.New("Network is already started") + } + + n.controlPassword = password + return nil +} + +// Start connection to the tor control port. This function blocks until the first +// connection attempt is finished. The first return value says whether the +// connection has been started; if true, the connection is up even if the first +// attempt failed. The second return value is the connection attempt error, or +// nil on success. +func (n *Network) Start() (bool, error) { n.controlMutex.Lock() if n.stoppedSignal != nil { - // This is an error, because address/password might not be the same n.controlMutex.Unlock() return false, errors.New("Network is already started") } - + if n.controlAddress == "" { + n.controlMutex.Unlock() + return false, errors.New("Control address not configured") + } n.stopSignal = make(chan struct{}) n.stoppedSignal = make(chan struct{}) - n.controlAddress = address - n.controlPassword = password n.controlMutex.Unlock() connectChannel := make(chan error) @@ -176,10 +197,8 @@ func chooseSocksAddress(addresses []string, controlAddress string) (socksAddress return selected, errors.New("No SOCKS port configured") } - // controlAddress is in the form of tcp:// or unix:// - if strings.HasPrefix(controlAddress, "tcp:") { - _, addrport, _ := bulbutils.ParseControlPortString(controlAddress) - addr, _, _ := net.SplitHostPort(addrport) + if !strings.HasPrefix(controlAddress, "unix:") { + addr, _, _ := net.SplitHostPort(controlAddress) preferredIP = net.ParseIP(addr) torOnLocalhost = preferredIP.IsLoopback() } @@ -467,8 +486,6 @@ func (n *Network) run(connectChannel chan<- error) { n.conn.Close() n.conn = nil } - n.controlAddress = "" - n.controlPassword = "" n.stoppedSignal = nil n.status = ricochet.NetworkStatus{} n.controlMutex.Unlock() @@ -569,10 +586,13 @@ func (n *Network) connectControl() error { } func createConnection(address, password string) (*bulb.Conn, error) { - net, addr, err := bulbutils.ParseControlPortString(address) - if err != nil { - log.Printf("Parsing control network address '%s' failed: %v", address, err) - return nil, err + var net, addr string + if strings.HasPrefix(address, "unix:") { + net = "unix" + addr = address[5:] + } else { + net = "tcp" + addr = address } conn, err := bulb.Dial(net, addr) @@ -590,7 +610,7 @@ func createConnection(address, password string) (*bulb.Conn, error) { conn.StartAsyncReader() - log.Print("Control connected!") + log.Printf("Control connection to %s successful", address) return conn, nil } diff --git a/core/ricochet.go b/core/ricochet.go index 38db7c5..ad5395f 100644 --- a/core/ricochet.go +++ b/core/ricochet.go @@ -6,6 +6,8 @@ import ( "math" "math/big" "math/rand" + "net" + "os" ) type Ricochet struct { @@ -14,18 +16,15 @@ type Ricochet struct { Identity *Identity } -func (core *Ricochet) Init(conf *Config) error { +func (core *Ricochet) Init(conf *Config) (err error) { initRand() - var err error core.Config = conf - core.Network = CreateNetwork() - core.Identity, err = CreateIdentity(core) - if err != nil { - return err - } - return nil + core.Network = CreateNetwork() + core.setupNetwork() + core.Identity, err = CreateIdentity(core) + return } func initRand() { @@ -36,3 +35,25 @@ func initRand() { rand.Seed(n.Int64()) } + +func (core *Ricochet) setupNetwork() { + socket := os.Getenv("TOR_CONTROL_SOCKET") + host := os.Getenv("TOR_CONTROL_HOST") + port := os.Getenv("TOR_CONTROL_PORT") + passwd := os.Getenv("TOR_CONTROL_PASSWD") + + if socket != "" { + core.Network.SetControlAddress("unix:" + socket) + } else if host != "" { + if port == "" { + port = "9051" + } + core.Network.SetControlAddress(net.JoinHostPort(host, port)) + } else { + core.Network.SetControlAddress("127.0.0.1:9051") + } + + if passwd != "" { + core.Network.SetControlPassword(passwd) + } +} diff --git a/core/rpcserver.go b/core/rpcserver.go index d891700..0af3a86 100644 --- a/core/rpcserver.go +++ b/core/rpcserver.go @@ -54,7 +54,7 @@ func (s *RpcServer) MonitorNetwork(req *ricochet.MonitorNetworkRequest, stream r func (s *RpcServer) StartNetwork(ctx context.Context, req *ricochet.StartNetworkRequest) (*ricochet.NetworkStatus, error) { // err represents the result of the first connection attempt, but as long // as 'ok' is true, the network has started and this call was successful. - ok, err := s.Core.Network.Start("tcp://127.0.0.1:9051", "") + ok, err := s.Core.Network.Start() if !ok { return nil, err }