mirror of
https://github.com/progval/irctest.git
synced 2025-04-05 14:59:49 +00:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
e9e37f5438 | |||
2b6b666426 | |||
d218d2f98d | |||
52178a99e5 | |||
7f2a631a1a | |||
cd9f801b92 | |||
ccd647ea61 | |||
9de64159ba | |||
638f959c95 |
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
python-version: 3.11
|
python-version: 3.11
|
||||||
|
|
||||||
- name: Cache dependencies
|
- name: Cache dependencies
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cache
|
~/.cache
|
||||||
|
4
.github/workflows/test-devel.yml
vendored
4
.github/workflows/test-devel.yml
vendored
@ -120,6 +120,8 @@ jobs:
|
|||||||
path: ircd-hybrid
|
path: ircd-hybrid
|
||||||
ref: 8.2.x
|
ref: 8.2.x
|
||||||
repository: ircd-hybrid/ircd-hybrid
|
repository: ircd-hybrid/ircd-hybrid
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: sudo apt-get install atheme-services faketime libjansson-dev
|
||||||
- name: Build Hybrid
|
- name: Build Hybrid
|
||||||
run: |
|
run: |
|
||||||
cd $GITHUB_WORKSPACE/ircd-hybrid/
|
cd $GITHUB_WORKSPACE/ircd-hybrid/
|
||||||
@ -558,7 +560,7 @@ jobs:
|
|||||||
repository: ergochat/ergo
|
repository: ergochat/ergo
|
||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ^1.23.0
|
go-version: ^1.24.0
|
||||||
- run: go version
|
- run: go version
|
||||||
- name: Build Ergo
|
- name: Build Ergo
|
||||||
run: |
|
run: |
|
||||||
|
4
.github/workflows/test-stable.yml
vendored
4
.github/workflows/test-stable.yml
vendored
@ -161,6 +161,8 @@ jobs:
|
|||||||
path: ircd-hybrid
|
path: ircd-hybrid
|
||||||
ref: 8.2.39
|
ref: 8.2.39
|
||||||
repository: ircd-hybrid/ircd-hybrid
|
repository: ircd-hybrid/ircd-hybrid
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: sudo apt-get install atheme-services faketime libjansson-dev
|
||||||
- name: Build Hybrid
|
- name: Build Hybrid
|
||||||
run: |
|
run: |
|
||||||
cd $GITHUB_WORKSPACE/ircd-hybrid/
|
cd $GITHUB_WORKSPACE/ircd-hybrid/
|
||||||
@ -636,7 +638,7 @@ jobs:
|
|||||||
repository: ergochat/ergo
|
repository: ergochat/ergo
|
||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ^1.23.0
|
go-version: ^1.24.0
|
||||||
- run: go version
|
- run: go version
|
||||||
- name: Build Ergo
|
- name: Build Ergo
|
||||||
run: |
|
run: |
|
||||||
|
@ -66,8 +66,13 @@ options {{
|
|||||||
warningtimeout = 4h
|
warningtimeout = 4h
|
||||||
}}
|
}}
|
||||||
|
|
||||||
module {{ name = "{module_prefix}sasl" }}
|
module {{ name = "ns_sasl" }} # since 2.1.13
|
||||||
module {{ name = "enc_bcrypt" }}
|
module {{ name = "sasl" }} # 2.1.2 to 2.1.12
|
||||||
|
module {{ name = "m_sasl" }} # 2.0 to 2.1.1
|
||||||
|
|
||||||
|
module {{ name = "enc_sha2" }} # 2.1
|
||||||
|
module {{ name = "enc_sha256" }} # 2.0
|
||||||
|
|
||||||
module {{ name = "ns_cert" }}
|
module {{ name = "ns_cert" }}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -123,7 +128,6 @@ class AnopeController(BaseServicesController, DirectoryBasedController):
|
|||||||
protocol=protocol,
|
protocol=protocol,
|
||||||
server_hostname=server_hostname,
|
server_hostname=server_hostname,
|
||||||
server_port=server_port,
|
server_port=server_port,
|
||||||
module_prefix="" if self.software_version >= (2, 1, 2) else "m_",
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ privset "omnioper" {{
|
|||||||
privs = oper:general, oper:privs, oper:testline, oper:kill, oper:operwall, oper:message,
|
privs = oper:general, oper:privs, oper:testline, oper:kill, oper:operwall, oper:message,
|
||||||
oper:routing, oper:kline, oper:unkline, oper:xline,
|
oper:routing, oper:kline, oper:unkline, oper:xline,
|
||||||
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
|
oper:resv, oper:cmodes, oper:mass_notice, oper:wallops,
|
||||||
oper:remoteban,
|
oper:remoteban, oper:local_kill,
|
||||||
usermode:servnotice, auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes,
|
usermode:servnotice, auspex:oper, auspex:hostname, auspex:umodes, auspex:cmodes,
|
||||||
oper:admin, oper:die, oper:rehash, oper:spy, oper:grant;
|
oper:admin, oper:die, oper:rehash, oper:spy, oper:grant;
|
||||||
}};
|
}};
|
||||||
|
@ -19,7 +19,7 @@ TEMPLATE_CONFIG = """
|
|||||||
|
|
||||||
<class
|
<class
|
||||||
name="ServerOperators"
|
name="ServerOperators"
|
||||||
commands="WALLOPS GLOBOPS"
|
commands="WALLOPS GLOBOPS KILL"
|
||||||
privs="channels/auspex users/auspex channels/auspex servers/auspex"
|
privs="channels/auspex users/auspex channels/auspex servers/auspex"
|
||||||
>
|
>
|
||||||
<type
|
<type
|
||||||
|
@ -24,7 +24,7 @@ Y:10:90::100:512000:100.100:100.100:
|
|||||||
I::{password_field}:::10::
|
I::{password_field}:::10::
|
||||||
|
|
||||||
# O:<TARGET Host NAME>:<Password>:<Nickname>:<Port>:<Class>:<Flags>:
|
# O:<TARGET Host NAME>:<Password>:<Nickname>:<Port>:<Class>:<Flags>:
|
||||||
O:*:operpassword:operuser::::
|
O:*:operpassword:operuser:::K:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ from irctest.basecontrollers import (
|
|||||||
NotImplementedByController,
|
NotImplementedByController,
|
||||||
)
|
)
|
||||||
from irctest.cases import BaseServerTestCase
|
from irctest.cases import BaseServerTestCase
|
||||||
|
from irctest.client_mock import ClientMock
|
||||||
from irctest.exceptions import NoMessageException
|
from irctest.exceptions import NoMessageException
|
||||||
from irctest.patma import ANYSTR
|
from irctest.patma import ANYSTR
|
||||||
|
|
||||||
@ -496,6 +497,53 @@ class SableServicesController(BaseServicesController):
|
|||||||
os.killpg(self.pgroup_id, signal.SIGKILL)
|
os.killpg(self.pgroup_id, signal.SIGKILL)
|
||||||
super().kill_proc()
|
super().kill_proc()
|
||||||
|
|
||||||
|
def wait_for_services(self) -> None:
|
||||||
|
# by default, wait_for_services() connects a user that sends a HELP command
|
||||||
|
# to NickServ and assumes services are up when it receives a non-ERR_NOSUCHNICK
|
||||||
|
# reply.
|
||||||
|
# However, with Sable, NickServ is always up, even when services are not linked,
|
||||||
|
# so we need to check a different way. We check presence of a non-EXTERNAL
|
||||||
|
# value to the sasl capability, but LINKS would
|
||||||
|
if self.services_up:
|
||||||
|
# Don't check again if they are already available
|
||||||
|
return
|
||||||
|
self.server_controller.wait_for_port()
|
||||||
|
|
||||||
|
c = ClientMock(name="chkSvs", show_io=True)
|
||||||
|
c.connect(self.server_controller.hostname, self.server_controller.port)
|
||||||
|
c.sendLine("NICK chkSvs")
|
||||||
|
c.sendLine("USER chk chk chk chk")
|
||||||
|
time.sleep(self.server_controller.sync_sleep_time)
|
||||||
|
got_end_of_motd = False
|
||||||
|
while not got_end_of_motd:
|
||||||
|
for msg in c.getMessages(synchronize=False):
|
||||||
|
if msg.command == "PING":
|
||||||
|
# Hi Unreal
|
||||||
|
c.sendLine("PONG :" + msg.params[0])
|
||||||
|
if msg.command in ("376", "422"): # RPL_ENDOFMOTD / ERR_NOMOTD
|
||||||
|
got_end_of_motd = True
|
||||||
|
|
||||||
|
timeout = time.time() + 10
|
||||||
|
while not self.services_up:
|
||||||
|
if time.time() > timeout:
|
||||||
|
raise Exception("Timeout while waiting for services")
|
||||||
|
c.sendLine("CAP LS 302")
|
||||||
|
|
||||||
|
msgs = self.getNickServResponse(c, timeout=1)
|
||||||
|
for msg in msgs:
|
||||||
|
if msg.command == "CAP":
|
||||||
|
pass
|
||||||
|
for token in msg.params[-1].split():
|
||||||
|
if token.startswith("sasl="):
|
||||||
|
if "PLAIN" in token.removeprefix("sasl=").split(","):
|
||||||
|
# SASL PLAIN is available, so services are linked.
|
||||||
|
self.services_up = True
|
||||||
|
break
|
||||||
|
|
||||||
|
c.sendLine("QUIT")
|
||||||
|
c.getMessages()
|
||||||
|
c.disconnect()
|
||||||
|
|
||||||
|
|
||||||
def get_irctest_controller_class() -> Type[SableController]:
|
def get_irctest_controller_class() -> Type[SableController]:
|
||||||
return SableController
|
return SableController
|
||||||
|
67
irctest/server_tests/kill.py
Normal file
67
irctest/server_tests/kill.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
"""
|
||||||
|
The KILL command (`Modern <https://modern.ircdocs.horse/#kill-message>`__)
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from irctest import cases
|
||||||
|
from irctest.numerics import ERR_NOPRIVILEGES, RPL_YOUREOPER
|
||||||
|
|
||||||
|
|
||||||
|
class KillTestCase(cases.BaseServerTestCase):
|
||||||
|
@cases.mark_specifications("Modern")
|
||||||
|
@cases.xfailIfSoftware(["Sable"], "https://github.com/Libera-Chat/sable/issues/154")
|
||||||
|
def testKill(self):
|
||||||
|
self.connectClient("ircop", name="ircop")
|
||||||
|
self.connectClient("alice", name="alice")
|
||||||
|
self.connectClient("bob", name="bob")
|
||||||
|
|
||||||
|
self.sendLine("ircop", "OPER operuser operpassword")
|
||||||
|
self.assertIn(
|
||||||
|
RPL_YOUREOPER,
|
||||||
|
[m.command for m in self.getMessages("ircop")],
|
||||||
|
fail_msg="OPER failed",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.sendLine("alice", "KILL bob :some arbitrary reason")
|
||||||
|
self.assertIn(
|
||||||
|
ERR_NOPRIVILEGES,
|
||||||
|
[m.command for m in self.getMessages("alice")],
|
||||||
|
fail_msg="unprivileged KILL not rejected",
|
||||||
|
)
|
||||||
|
# bob is not killed
|
||||||
|
self.getMessages("bob")
|
||||||
|
|
||||||
|
self.sendLine("alice", "KILL alice :some arbitrary reason")
|
||||||
|
self.assertIn(
|
||||||
|
ERR_NOPRIVILEGES,
|
||||||
|
[m.command for m in self.getMessages("alice")],
|
||||||
|
fail_msg="unprivileged KILL not rejected",
|
||||||
|
)
|
||||||
|
# alice is not killed
|
||||||
|
self.getMessages("alice")
|
||||||
|
|
||||||
|
# privileged KILL should succeed
|
||||||
|
self.sendLine("ircop", "KILL alice :some arbitrary reason")
|
||||||
|
self.getMessages("ircop")
|
||||||
|
self.assertDisconnected("alice")
|
||||||
|
|
||||||
|
self.sendLine("ircop", "KILL bob :some arbitrary reason")
|
||||||
|
self.getMessages("ircop")
|
||||||
|
self.assertDisconnected("bob")
|
||||||
|
|
||||||
|
@cases.mark_specifications("Ergo")
|
||||||
|
def testKillOneArgument(self):
|
||||||
|
self.connectClient("ircop", name="ircop")
|
||||||
|
self.connectClient("alice", name="alice")
|
||||||
|
|
||||||
|
self.sendLine("ircop", "OPER operuser operpassword")
|
||||||
|
self.assertIn(
|
||||||
|
RPL_YOUREOPER,
|
||||||
|
[m.command for m in self.getMessages("ircop")],
|
||||||
|
fail_msg="OPER failed",
|
||||||
|
)
|
||||||
|
|
||||||
|
# 1-argument kill command, accepted by Ergo and some implementations
|
||||||
|
self.sendLine("ircop", "KILL alice")
|
||||||
|
self.getMessages("ircop")
|
||||||
|
self.assertDisconnected("alice")
|
2
mypy.ini
2
mypy.ini
@ -1,5 +1,5 @@
|
|||||||
[mypy]
|
[mypy]
|
||||||
python_version = 3.8
|
python_version = 3.9
|
||||||
warn_return_any = True
|
warn_return_any = True
|
||||||
warn_unused_configs = True
|
warn_unused_configs = True
|
||||||
|
|
||||||
|
@ -33,6 +33,9 @@ software:
|
|||||||
devel: "8.2.x"
|
devel: "8.2.x"
|
||||||
devel_release: null
|
devel_release: null
|
||||||
path: ircd-hybrid
|
path: ircd-hybrid
|
||||||
|
pre_deps:
|
||||||
|
- name: "Install system dependencies"
|
||||||
|
run: "sudo apt-get install atheme-services faketime libjansson-dev"
|
||||||
separate_build_job: true
|
separate_build_job: true
|
||||||
build_script: |
|
build_script: |
|
||||||
cd $GITHUB_WORKSPACE/ircd-hybrid/
|
cd $GITHUB_WORKSPACE/ircd-hybrid/
|
||||||
@ -136,7 +139,7 @@ software:
|
|||||||
pre_deps:
|
pre_deps:
|
||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: '^1.23.0'
|
go-version: '^1.24.0'
|
||||||
- run: go version
|
- run: go version
|
||||||
separate_build_job: false
|
separate_build_job: false
|
||||||
build_script: |
|
build_script: |
|
||||||
|
Reference in New Issue
Block a user