feat: client-side TLS for encrypted client connections
Accept TLS-encrypted connections from IRC clients. Auto-generates a self-signed EC P-256 listener certificate (bouncer.pem) when no custom cert is provided. Remove CTCP response items from roadmap (stealth by design -- router already suppresses all CTCP except ACTION). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,8 +11,10 @@ from bouncer.cert import (
|
||||
delete_cert,
|
||||
fingerprint,
|
||||
generate_cert,
|
||||
generate_listener_cert,
|
||||
has_cert,
|
||||
list_certs,
|
||||
listener_cert_path,
|
||||
)
|
||||
|
||||
|
||||
@@ -22,6 +24,41 @@ def data_dir(tmp_path: Path) -> Path:
|
||||
return tmp_path
|
||||
|
||||
|
||||
class TestGenerateListenerCert:
|
||||
def test_creates_pem_with_cn_bouncer(self, data_dir: Path) -> None:
|
||||
from cryptography import x509 as x509_mod
|
||||
from cryptography.x509.oid import NameOID
|
||||
|
||||
pem = generate_listener_cert(data_dir)
|
||||
assert pem.is_file()
|
||||
assert pem == listener_cert_path(data_dir)
|
||||
|
||||
cert_data = pem.read_bytes()
|
||||
cert_obj = x509_mod.load_pem_x509_certificate(cert_data)
|
||||
cn = cert_obj.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[0].value
|
||||
assert cn == "bouncer"
|
||||
|
||||
content = pem.read_text()
|
||||
assert "BEGIN CERTIFICATE" in content
|
||||
assert "BEGIN PRIVATE KEY" in content
|
||||
|
||||
mode = pem.stat().st_mode & 0o777
|
||||
assert mode == 0o600
|
||||
|
||||
def test_idempotent(self, data_dir: Path) -> None:
|
||||
pem1 = generate_listener_cert(data_dir)
|
||||
fp1 = fingerprint(pem1)
|
||||
mtime1 = pem1.stat().st_mtime
|
||||
|
||||
pem2 = generate_listener_cert(data_dir)
|
||||
fp2 = fingerprint(pem2)
|
||||
mtime2 = pem2.stat().st_mtime
|
||||
|
||||
assert pem1 == pem2
|
||||
assert fp1 == fp2
|
||||
assert mtime1 == mtime2 # file not regenerated
|
||||
|
||||
|
||||
class TestCertPath:
|
||||
def test_standard_path(self, data_dir: Path) -> None:
|
||||
p = cert_path(data_dir, "libera", "fabesune")
|
||||
|
||||
Reference in New Issue
Block a user