diff --git a/letsencrypt/client/standalone_authenticator.py b/letsencrypt/client/standalone_authenticator.py index 3e9a4381c..c4a1c63b1 100644 --- a/letsencrypt/client/standalone_authenticator.py +++ b/letsencrypt/client/standalone_authenticator.py @@ -281,9 +281,13 @@ class StandaloneAuthenticator(object): if proc.wait() != 0: raise OSError("netstat subprocess failed") lines = [x.split() for x in stdout.split("\n")[2:] if x] - listeners = [L[6] for L in lines if L[0] == 'tcp' \ - and L[5] == 'LISTEN' \ - and L[3] == '0.0.0.0:{0}'.format(port)] + listeners = [L[6] for L in lines if + # IPv4 socket case + (L[0] == 'tcp' and L[5] == 'LISTEN' \ + and L[3] == '0.0.0.0:{0}'.format(port)) or \ + # IPv6 socket case + (L[0] == 'tcp6' and L[5] == 'LISTEN' \ + and L[3] == ':::{0}'.format(port))] if listeners: pid, name = listeners[0].split("/") display = zope.component.getUtility(interfaces.IDisplay) diff --git a/letsencrypt/client/tests/standalone_authenticator_test.py b/letsencrypt/client/tests/standalone_authenticator_test.py index 940ead6d0..9787073b1 100644 --- a/letsencrypt/client/tests/standalone_authenticator_test.py +++ b/letsencrypt/client/tests/standalone_authenticator_test.py @@ -231,6 +231,25 @@ tcp 0 0 0.0.0.0:1728 0.0.0.0:* LISTEN self.assertTrue(result) self.assertEqual(mock_get_utility.call_count, 1) + @mock.patch("letsencrypt.client.standalone_authenticator.subprocess.Popen") + @mock.patch("letsencrypt.client.standalone_authenticator." + "zope.component.getUtility") + def test_has_relevant_ipv6_line(self, mock_get_utility, mock_popen): + # pylint: disable=line-too-long,trailing-whitespace + subprocess_object = mock.MagicMock() + subprocess_object.communicate.return_value = ( + """Active Internet connections (servers and established) +Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name +tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN 1234/foo +tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 2345/bar +tcp6 0 0 :::17 :::* LISTEN 11111/hello +tcp 0 0 0.0.0.0:1728 0.0.0.0:* LISTEN 2345/bar """, + "I am the standard error") + subprocess_object.wait.return_value = 0 + mock_popen.return_value = subprocess_object + result = self.authenticator.already_listening(17) + self.assertTrue(result) + self.assertEqual(mock_get_utility.call_count, 1) class PerformTest(unittest.TestCase): """Tests for perform() method."""