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.
This commit is contained in:
John Brooks 2016-11-05 22:09:18 -06:00
parent 9c0110dca2
commit 1be58828fe
3 changed files with 72 additions and 31 deletions

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}