diff --git a/config.go b/config.go index 2441f11042d..78e7825d072 100644 --- a/config.go +++ b/config.go @@ -502,12 +502,6 @@ func loadConfig() (*config, error) { case cfg.DisableListen && (cfg.Tor.V2 || cfg.Tor.V3): return nil, errors.New("listening must be enabled when " + "enabling inbound connections over Tor") - case cfg.Tor.Active && (!cfg.Tor.V2 && !cfg.Tor.V3): - // If an onion service version wasn't selected, we'll assume the - // user is only interested in outbound connections over Tor. - // Therefore, we'll disable listening in order to avoid - // inadvertent leaks. - cfg.DisableListen = true } if cfg.Tor.PrivateKeyPath == "" { @@ -866,9 +860,14 @@ func loadConfig() (*config, error) { // Listen on the default interface/port if no listeners were specified. // An empty address string means default interface/address, which on - // most unix systems is the same as 0.0.0.0. + // most unix systems is the same as 0.0.0.0. If Tor is active, we + // default to only listening on localhost for hidden service + // connections. if len(cfg.RawListeners) == 0 { addr := fmt.Sprintf(":%d", defaultPeerPort) + if cfg.Tor.Active { + addr = fmt.Sprintf("localhost:%d", defaultPeerPort) + } cfg.RawListeners = append(cfg.RawListeners, addr) } @@ -948,20 +947,6 @@ func loadConfig() (*config, error) { } } - // Ensure that we are only listening on localhost if Tor inbound support - // is enabled. - if cfg.Tor.V2 || cfg.Tor.V3 { - for _, addr := range cfg.Listeners { - if lncfg.IsLoopback(addr.String()) { - continue - } - - return nil, errors.New("lnd must *only* be listening " + - "on localhost when running with Tor inbound " + - "support enabled") - } - } - // Ensure that the specified minimum backoff is below or equal to the // maximum backoff. if cfg.MinBackoff > cfg.MaxBackoff { diff --git a/tor/controller.go b/tor/controller.go index 9b11bde66a4..aa8f74d5c9a 100644 --- a/tor/controller.go +++ b/tor/controller.go @@ -163,7 +163,7 @@ func parseTorReply(reply string) map[string]string { } // authenticate authenticates the connection between the controller and the -// Tor server using the SAFECOOKIE authentication method. +// Tor server using the SAFECOOKIE or NULL authentication method. func (c *Controller) authenticate() error { // Before proceeding to authenticate the connection, we'll retrieve // the authentication cookie of the Tor server. This will be used @@ -176,6 +176,13 @@ func (c *Controller) authenticate() error { "%v", err) } + // If cookie is empty and there's no error, we have a NULL + // authentication method that we should use instead. + if len(cookie) == 0 { + _, _, err := c.sendCommand("AUTHENTICATE") + return err + } + // Authenticating using the SAFECOOKIE authentication method is a two // step process. We'll kick off the authentication routine by sending // the AUTHCHALLENGE command followed by a hex-encoded 32-byte nonce. @@ -274,17 +281,21 @@ func (c *Controller) getAuthCookie() ([]byte, error) { c.version = version // Ensure that the Tor server supports the SAFECOOKIE authentication - // method. + // method or the NULL method. If NULL, we don't need the cookie info + // below this loop, so we just return. safeCookieSupport := false for _, authMethod := range authMethods { if authMethod == "SAFECOOKIE" { safeCookieSupport = true } + if authMethod == "NULL" { + return nil, nil + } } if !safeCookieSupport { return nil, errors.New("the Tor server is currently not " + - "configured for cookie authentication") + "configured for cookie or null authentication") } // Read the cookie from the file and ensure it has the correct length. @@ -374,7 +385,7 @@ func (c *Controller) ProtocolInfo() ([]string, string, string, error) { } cookieFile, ok := info["COOKIEFILE"] - if !ok { + if !ok && !strings.Contains(methods, "NULL") { return nil, "", "", errors.New("cookie file path not found " + "in reply") }