Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add various validation tests #221

Merged
merged 6 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ jobs:
uses: actions/checkout@v3
with:
path: ngircd
ref: rel-26.1
ref: 0714466af88d71d6c395629cd7fb624b099507d4
repository: ngircd/ngircd
- name: Build ngircd
run: |
Expand Down
6 changes: 4 additions & 2 deletions irctest/server_tests/chmodes/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def testKeyNormal(self):

@pytest.mark.parametrize(
"key",
["passphrase with spaces", "long" * 100, ""],
ids=["spaces", "long", "empty"],
["passphrase with spaces", "long" * 100, "", " "],
ids=["spaces", "long", "empty", "only-space"],
)
@cases.mark_specifications("RFC2812", "Modern")
def testKeyValidation(self, key):
Expand Down Expand Up @@ -84,6 +84,8 @@ def testKeyValidation(self, key):
"ngIRCd does not validate channel keys: "
"https://github.com/ngircd/ngircd/issues/290"
)
if key == " " and self.controller.software_name == "irc2":
pytest.xfail("irc2 rewrites non-empty keys that contain only spaces")

self.connectClient("bar")
self.joinChannel(1, "#chan")
Expand Down
59 changes: 58 additions & 1 deletion irctest/server_tests/connection_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
TODO: cross-reference Modern and RFC 2812 too
"""

import time

from irctest import cases
from irctest.client_mock import ConnectionClosed
from irctest.numerics import ERR_NEEDMOREPARAMS, ERR_PASSWDMISMATCH
Expand Down Expand Up @@ -133,7 +135,7 @@ def testNickCollision(self):
self.assertNotEqual(
m.command,
"001",
"Received 001 after registering with the nick of a " "registered user.",
"Received 001 after registering with the nick of a registered user.",
)

def testEarlyNickCollision(self):
Expand Down Expand Up @@ -206,3 +208,58 @@ def testEmptyRealname(self):
command=ERR_NEEDMOREPARAMS,
params=[StrRe(r"(\*|foo)"), "USER", ANYSTR],
)

def testNonutf8Realname(self):
self.addClient()
self.sendLine(1, "NICK foo")
line = b"USER username * * :i\xe8rc\xe9\r\n"
print("1 -> S (repr): " + repr(line))
self.clients[1].conn.sendall(line)
for _ in range(10):
time.sleep(1)
d = self.clients[1].conn.recv(10000)
self.assertTrue(d, "Server closed connection")
print("S -> 1 (repr): " + repr(d))
if b" 001 " in d:
break
if b"ERROR " in d or b" FAIL " in d:
# Rejected; nothing more to test.
return
for line in d.split(b"\r\n"):
if line.startswith(b"PING "):
line = line.replace(b"PING", b"PONG") + b"\r\n"
print("1 -> S (repr): " + repr(line))
self.clients[1].conn.sendall(line)
else:
self.assertTrue(False, "stuck waiting")
self.sendLine(1, "WHOIS foo")
time.sleep(3) # for ngIRCd
d = self.clients[1].conn.recv(10000)
print("S -> 1 (repr): " + repr(d))
self.assertIn(b"username", d)

def testNonutf8Username(self):
self.addClient()
self.sendLine(1, "NICK foo")
self.sendLine(1, "USER 😊😊😊😊😊😊😊😊😊😊 * * :realname")
for _ in range(10):
time.sleep(1)
d = self.clients[1].conn.recv(10000)
self.assertTrue(d, "Server closed connection")
print("S -> 1 (repr): " + repr(d))
if b" 001 " in d:
break
if b" 468" in d or b"ERROR " in d:
# Rejected; nothing more to test.
return
for line in d.split(b"\r\n"):
if line.startswith(b"PING "):
line = line.replace(b"PING", b"PONG") + b"\r\n"
print("1 -> S (repr): " + repr(line))
self.clients[1].conn.sendall(line)
else:
self.assertTrue(False, "stuck waiting")
self.sendLine(1, "WHOIS foo")
d = self.clients[1].conn.recv(10000)
print("S -> 1 (repr): " + repr(d))
self.assertIn(b"realname", d)
22 changes: 22 additions & 0 deletions irctest/server_tests/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ def testPrivmsgNonexistentUser(self):
# ERR_NOSUCHNICK: 401 <sender> <recipient> :No such nick
self.assertMessageMatch(msg, command="401", params=["foo", "bar", ANYSTR])

@cases.mark_specifications("RFC1459", "RFC2812", "Modern")
@cases.xfailIfSoftware(
["irc2"],
"replies with ERR_NEEDMOREPARAMS instead of ERR_NOTEXTTOSEND",
)
def testEmptyPrivmsg(self):
self.connectClient("foo")
self.sendLine(1, "JOIN #chan")
self.getMessages(1) # synchronize
self.connectClient("bar")
self.sendLine(2, "JOIN #chan")
self.getMessages(2) # synchronize
self.getMessages(1) # synchronize
self.sendLine(1, "PRIVMSG #chan :")

self.assertMessageMatch(
self.getMessage(1),
command="412", # ERR_NOTEXTTOSEND
params=["foo", ANYSTR],
)
self.assertEqual(self.getMessages(2), [])


class NoticeTestCase(cases.BaseServerTestCase):
@cases.mark_specifications("RFC1459", "RFC2812")
Expand Down
35 changes: 35 additions & 0 deletions irctest/server_tests/utf8.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,38 @@ def testUtf8Validation(self):

if m.command in ("FAIL", "WARN"):
self.assertMessageMatch(m, params=["PRIVMSG", "INVALID_UTF8", ANYSTR])

def testNonutf8Realname(self):
self.connectClient("foo")
if "UTF8ONLY" not in self.server_support:
raise runner.IsupportTokenNotSupported("UTF8ONLY")

self.addClient()
self.sendLine(2, "NICK foo")
self.clients[2].conn.sendall(b"USER username * * :i\xe8rc\xe9\r\n")

d = self.clients[2].conn.recv(1024)
if b" FAIL " in d or b" 468 " in d: # ERR_INVALIDUSERNAME
return # nothing more to test
self.assertIn(b" 001 ", d)

self.sendLine(2, "WHOIS foo")
self.getMessages(2)

def testNonutf8Username(self):
self.connectClient("foo")
if "UTF8ONLY" not in self.server_support:
raise runner.IsupportTokenNotSupported("UTF8ONLY")

self.addClient()
self.sendLine(2, "NICK foo")
self.sendLine(2, "USER 😊😊😊😊😊😊😊😊😊😊 * * :realname")
m = self.getRegistrationMessage(2)
if m.command in ("FAIL", "468"): # ERR_INVALIDUSERNAME
return # nothing more to test
self.assertMessageMatch(
m,
command="001",
)
self.sendLine(2, "WHOIS foo")
self.getMessages(2)
2 changes: 1 addition & 1 deletion workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ software:
name: ngircd
repository: ngircd/ngircd
refs:
stable: rel-26.1
stable: 0714466af88d71d6c395629cd7fb624b099507d4 # two years ahead of rel-26.1
release: null
devel: master
devel_release: null
Expand Down
Loading