BIND 10 trac2595, updated. e283a05caf9dd0aefc7cd08a405dbc47510fbd43 [2595] print SSL error on both SSLError and ECONNRESET

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jan 24 10:44:14 UTC 2013


The branch, trac2595 has been updated
       via  e283a05caf9dd0aefc7cd08a405dbc47510fbd43 (commit)
      from  7491dd625f34f755d9764cf9e116cd8374be1d88 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit e283a05caf9dd0aefc7cd08a405dbc47510fbd43
Author: Jelte Jansen <jelte at isc.org>
Date:   Thu Jan 24 11:43:57 2013 +0100

    [2595] print SSL error on both SSLError and ECONNRESET

-----------------------------------------------------------------------

Summary of changes:
 src/bin/bindctl/bindcmd.py            |   21 +++++++---
 src/bin/bindctl/tests/bindctl_test.py |   72 +++++++++++++++++++++++++++++----
 2 files changed, 81 insertions(+), 12 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/bindctl/bindcmd.py b/src/bin/bindctl/bindcmd.py
index 738b128..af599a4 100644
--- a/src/bin/bindctl/bindcmd.py
+++ b/src/bin/bindctl/bindcmd.py
@@ -214,6 +214,12 @@ WARNING: Python readline module isn't available, so the command line editor
 
         return True
 
+    def __print_check_ssl_msg(self):
+        self._print("Please check the logs of b10-cmdctl, there may "
+                    "be a problem accepting SSL connections, such "
+                    "as a permission problem on the server "
+                    "certificate file.")
+
     def _try_login(self, username, password):
         '''
         Attempts to log in to cmdctl by sending a POST with
@@ -229,15 +235,20 @@ WARNING: Python readline module isn't available, so the command line editor
         try:
             response = self.send_POST('/login', param)
             data = response.read().decode()
+            # return here (will raise error after try block)
             return (response, data)
+        except ssl.SSLError as err:
+            self._print("SSL error while sending login information: ", err)
+            if err.errno == ssl.SSL_ERROR_EOF:
+                self.__print_check_ssl_msg()
         except socket.error as err:
             self._print("Socket error while sending login information: ", err)
+            # An SSL setup error can also bubble up as a plain CONNRESET...
+            # (on some systems it usually does)
             if err.errno == errno.ECONNRESET:
-                self._print("Please check the logs of b10-cmdctl, there may "
-                            "be a problem accepting SSL connections, such "
-                            "as a permission problem on the server "
-                            "certificate file.")
-            raise FailToLogin()
+                self.__print_check_ssl_msg()
+            pass
+        raise FailToLogin()
 
     def login_to_cmdctl(self):
         '''Login to cmdctl with the username and password given by
diff --git a/src/bin/bindctl/tests/bindctl_test.py b/src/bin/bindctl/tests/bindctl_test.py
index 7c98439..2e8de8e 100644
--- a/src/bin/bindctl/tests/bindctl_test.py
+++ b/src/bin/bindctl/tests/bindctl_test.py
@@ -18,11 +18,14 @@ import unittest
 import isc.cc.data
 import os
 import io
+import errno
 import sys
 import socket
+import ssl
 import http.client
 import pwd
 import getpass
+import re
 from optparse import OptionParser
 from isc.config.config_data import ConfigData, MultiConfigData
 from isc.config.module_spec import ModuleSpec
@@ -355,21 +358,35 @@ class TestConfigCommands(unittest.TestCase):
            to the list in self.printed_messages'''
         self.printed_messages.append(" ".join(map(str, args)))
 
+    def __check_printed_message(self, expected_message, printed_message):
+        self.assertIsNotNone(re.match(expected_message, printed_message),
+                             "Printed message '" + printed_message +
+                             "' does not match '" + expected_message + "'")
+
+    def __check_printed_messages(self, expected_messages):
+        '''Helper test function to check the printed messages against a list
+           of regexps'''
+        for el in map(self.__check_printed_message,
+                      expected_messages,
+                      self.printed_messages):
+            pass
+
     def test_try_login(self):
         # Make sure __try_login raises the correct exception
         # upon failure of either send_POST or the read() on the
         # response
 
         orig_send_POST = self.tool.send_POST
+        expected_printed_messages = []
         try:
             def send_POST_raiseImmediately(self, params):
                 raise socket.error("test error")
 
             self.tool.send_POST = send_POST_raiseImmediately
             self.assertRaises(FailToLogin, self.tool._try_login, "foo", "bar")
-            self.assertIn('Socket error while sending login information:  test error',
-                          self.printed_messages)
-            self.assertEqual(1, len(self.printed_messages))
+            expected_printed_messages.append(
+                'Socket error while sending login information:  test error')
+            self.__check_printed_messages(expected_printed_messages)
 
             def create_send_POST_raiseOnRead(exception):
                 '''Create a replacement send_POST() method that raises
@@ -382,18 +399,59 @@ class TestConfigCommands(unittest.TestCase):
                     return MyResponse()
                 return send_POST_raiseOnRead
 
+            # basic socket error
             self.tool.send_POST =\
                 create_send_POST_raiseOnRead(socket.error("read error"))
             self.assertRaises(FailToLogin, self.tool._try_login, "foo", "bar")
-            self.assertIn('Socket error while sending login information:  read error',
-                          self.printed_messages)
-            self.assertEqual(2, len(self.printed_messages))
+            expected_printed_messages.append(
+                'Socket error while sending login information:  read error')
+            self.__check_printed_messages(expected_printed_messages)
+
+            # connection reset
+            exc = socket.error("connection reset")
+            exc.errno = errno.ECONNRESET
+            self.tool.send_POST =\
+                create_send_POST_raiseOnRead(exc)
+            self.assertRaises(FailToLogin, self.tool._try_login, "foo", "bar")
+            expected_printed_messages.append(
+                'Socket error while sending login information:  '
+                'connection reset')
+            expected_printed_messages.append(
+                'Please check the logs of b10-cmdctl, there may be a '
+                'problem accepting SSL connections, such as a permission '
+                'problem on the server certificate file.'
+            )
+            self.__check_printed_messages(expected_printed_messages)
+
+            # 'normal' SSL error
+            exc = ssl.SSLError()
+            self.tool.send_POST =\
+                create_send_POST_raiseOnRead(exc)
+            self.assertRaises(FailToLogin, self.tool._try_login, "foo", "bar")
+            expected_printed_messages.append(
+                'SSL error while sending login information:  .*')
+            self.__check_printed_messages(expected_printed_messages)
+
+            # 'EOF' SSL error
+            exc = ssl.SSLError()
+            exc.errno = ssl.SSL_ERROR_EOF
+            self.tool.send_POST =\
+                create_send_POST_raiseOnRead(exc)
+            self.assertRaises(FailToLogin, self.tool._try_login, "foo", "bar")
+            expected_printed_messages.append(
+                'SSL error while sending login information: .*')
+            expected_printed_messages.append(
+                'Please check the logs of b10-cmdctl, there may be a '
+                'problem accepting SSL connections, such as a permission '
+                'problem on the server certificate file.'
+            )
+            self.__check_printed_messages(expected_printed_messages)
 
             # any other exception should be passed through
             self.tool.send_POST =\
                 create_send_POST_raiseOnRead(ImportError())
             self.assertRaises(ImportError, self.tool._try_login, "foo", "bar")
-            self.assertEqual(2, len(self.printed_messages))
+            self.__check_printed_messages(expected_printed_messages)
 
         finally:
             self.tool.send_POST = orig_send_POST



More information about the bind10-changes mailing list