From: Jelte Jansen Date: Thu, 24 Jan 2013 10:43:57 +0000 (+0100) Subject: [2595] print SSL error on both SSLError and ECONNRESET X-Git-Tag: bind10-1.0.0-rc-release~76^2~8^2~4^2~1^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e283a05caf9dd0aefc7cd08a405dbc47510fbd43;p=thirdparty%2Fkea.git [2595] print SSL error on both SSLError and ECONNRESET --- diff --git a/src/bin/bindctl/bindcmd.py b/src/bin/bindctl/bindcmd.py index 738b1284c7..af599a4b69 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 7c984392f1..2e8de8e4bd 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