Merge pull request #2490 from aakselrod/tor-null-auth-and-listen-fixes

Tor null auth and listen fixes
This commit is contained in:
Olaoluwa Osuntokun 2019-03-15 14:53:12 -07:00 committed by GitHub
commit b4a1024ac7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 25 deletions

@ -516,12 +516,6 @@ func loadConfig() (*config, error) {
case cfg.DisableListen && (cfg.Tor.V2 || cfg.Tor.V3): case cfg.DisableListen && (cfg.Tor.V2 || cfg.Tor.V3):
return nil, errors.New("listening must be enabled when " + return nil, errors.New("listening must be enabled when " +
"enabling inbound connections over Tor") "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 == "" { if cfg.Tor.PrivateKeyPath == "" {
@ -880,9 +874,14 @@ func loadConfig() (*config, error) {
// Listen on the default interface/port if no listeners were specified. // Listen on the default interface/port if no listeners were specified.
// An empty address string means default interface/address, which on // 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 { if len(cfg.RawListeners) == 0 {
addr := fmt.Sprintf(":%d", defaultPeerPort) addr := fmt.Sprintf(":%d", defaultPeerPort)
if cfg.Tor.Active {
addr = fmt.Sprintf("localhost:%d", defaultPeerPort)
}
cfg.RawListeners = append(cfg.RawListeners, addr) cfg.RawListeners = append(cfg.RawListeners, addr)
} }
@ -962,20 +961,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 // Ensure that the specified minimum backoff is below or equal to the
// maximum backoff. // maximum backoff.
if cfg.MinBackoff > cfg.MaxBackoff { if cfg.MinBackoff > cfg.MaxBackoff {

@ -163,7 +163,7 @@ func parseTorReply(reply string) map[string]string {
} }
// authenticate authenticates the connection between the controller and the // 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 { func (c *Controller) authenticate() error {
// Before proceeding to authenticate the connection, we'll retrieve // Before proceeding to authenticate the connection, we'll retrieve
// the authentication cookie of the Tor server. This will be used // the authentication cookie of the Tor server. This will be used
@ -176,6 +176,13 @@ func (c *Controller) authenticate() error {
"%v", err) "%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 // Authenticating using the SAFECOOKIE authentication method is a two
// step process. We'll kick off the authentication routine by sending // step process. We'll kick off the authentication routine by sending
// the AUTHCHALLENGE command followed by a hex-encoded 32-byte nonce. // the AUTHCHALLENGE command followed by a hex-encoded 32-byte nonce.
@ -274,17 +281,21 @@ func (c *Controller) getAuthCookie() ([]byte, error) {
c.version = version c.version = version
// Ensure that the Tor server supports the SAFECOOKIE authentication // 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 safeCookieSupport := false
for _, authMethod := range authMethods { for _, authMethod := range authMethods {
if authMethod == "SAFECOOKIE" { if authMethod == "SAFECOOKIE" {
safeCookieSupport = true safeCookieSupport = true
} }
if authMethod == "NULL" {
return nil, nil
}
} }
if !safeCookieSupport { if !safeCookieSupport {
return nil, errors.New("the Tor server is currently not " + 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. // 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"] cookieFile, ok := info["COOKIEFILE"]
if !ok { if !ok && !strings.Contains(methods, "NULL") {
return nil, "", "", errors.New("cookie file path not found " + return nil, "", "", errors.New("cookie file path not found " +
"in reply") "in reply")
} }