From 6b6b86415dd981859945009880a480344f0d242c Mon Sep 17 00:00:00 2001 From: Valentin Lorentz Date: Fri, 26 Feb 2021 21:07:15 +0100 Subject: [PATCH] Make testKeyValidation not Oragono-specific. --- .github/workflows/inspircd.yml | 3 +- .../server_tests/test_channel_operations.py | 63 +++++++++++++++++-- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/.github/workflows/inspircd.yml b/.github/workflows/inspircd.yml index 7a5f8af..c0f19b0 100644 --- a/.github/workflows/inspircd.yml +++ b/.github/workflows/inspircd.yml @@ -50,5 +50,6 @@ jobs: run: | # testNoticeNonexistentChannel fails because of https://github.com/inspircd/inspircd/issues/1849 # testDirectMessageEcho fails because of https://github.com/inspircd/inspircd/issues/1851 - PATH=~/.local/bin:$PATH pytest --controller irctest.controllers.inspircd -k 'not Oragono and not deprecated and not strict and not testNoticeNonexistentChannel and not testDirectMessageEcho' + # testKeyValidation fails because of https://github.com/inspircd/inspircd/issues/1850 + PATH=~/.local/bin:$PATH pytest --controller irctest.controllers.inspircd -k 'not Oragono and not deprecated and not strict and not testNoticeNonexistentChannel and not testDirectMessageEcho and not testKeyValidation' diff --git a/irctest/server_tests/test_channel_operations.py b/irctest/server_tests/test_channel_operations.py index e975703..733c9e0 100644 --- a/irctest/server_tests/test_channel_operations.py +++ b/irctest/server_tests/test_channel_operations.py @@ -856,7 +856,7 @@ class NoCTCPTestCase(cases.BaseServerTestCase): class KeyTestCase(cases.BaseServerTestCase): - @cases.mark_specifications("RFC2812") + @cases.mark_specifications("RFC1459", "RFC2812") def testKeyNormal(self): self.connectClient("bar") self.joinChannel(1, "#chan") @@ -874,15 +874,66 @@ class KeyTestCase(cases.BaseServerTestCase): reply = self.getMessages(2) self.assertMessageEqual(reply[0], command="JOIN", params=["#chan"]) - @cases.mark_specifications("Oragono") + @cases.mark_specifications("RFC2812") def testKeyValidation(self): + """ + key = 1*23( %x01-05 / %x07-08 / %x0C / %x0E-1F / %x21-7F ) + ; any 7-bit US_ASCII character, + ; except NUL, CR, LF, FF, h/v TABs, and " " + + """ # oragono issue #1021 self.connectClient("bar") self.joinChannel(1, "#chan") - self.sendLine(1, "MODE #chan +k :invalid channel passphrase") - reply = self.getMessages(1) - self.assertNotIn(ERR_UNKNOWNERROR, {msg.command for msg in reply}) - self.assertIn(ERR_INVALIDMODEPARAM, {msg.command for msg in reply}) + self.sendLine(1, "MODE #chan +k :passphrase with spaces") + + # The spec requires no space; but doesn't say what to do + # if there is one. + # Let's check the various alternatives + + replies = self.getMessages(1) + self.assertNotIn( + ERR_UNKNOWNERROR, + {msg.command for msg in replies}, + fail_msg="Sending an invalid key (with a space) caused an " + "ERR_UNKNOWNERROR instead of being handled explicitly " + "(eg. ERR_INVALIDMODEPARAM or truncation): {msg}", + ) + + if ERR_INVALIDMODEPARAM in {msg.command for msg in replies}: + # First option: ERR_INVALIDMODEPARAM (eg. Oragono) + return + + # Second and third options: truncating the key (eg. UnrealIRCd) + # or replacing spaces (eg. Charybdis) + mode_commands = [msg for msg in replies if msg.command == "MODE"] + self.assertGreaterEqual( + len(mode_commands), + 1, + fail_msg="Sending an invalid key (with a space) triggered " + "neither ERR_UNKNOWNERROR, ERR_INVALIDMODEPARAM, or a MODE. " + "Only these: {}", + extra_format=(replies,), + ) + self.assertLessEqual( + len(mode_commands), + 1, + fail_msg="Sending an invalid key (with a space) triggered " + "multiple MODE responses: {}", + extra_format=(replies,), + ) + + mode_command = mode_commands[0] + if mode_command.params == ["#chan", "+k", "passphrase"]: + key = "passphrase" + elif mode_command.params == ["#chan", "+k", "passphrasewithspaces"]: + key = "passphrasewithspaces" + elif mode_command.params == ["#chan", "+k", "passphrase with spaces"]: + raise self.failureException("Invalid key (with a space) was not rejected.") + + self.connectClient("foo") + self.sendLine(2, f"JOIN #chan {key}") + self.assertMessageEqual(self.getMessage(2), command="JOIN", params=["#chan"]) class AuditoriumTestCase(cases.BaseServerTestCase):