mirror of
https://github.com/progval/irctest.git
synced 2025-04-06 23:39:46 +00:00
Add TLS certificate check tests for clients.
This commit is contained in:
@ -1,5 +1,7 @@
|
|||||||
|
import ssl
|
||||||
import time
|
import time
|
||||||
import socket
|
import socket
|
||||||
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
import functools
|
import functools
|
||||||
import collections
|
import collections
|
||||||
@ -11,6 +13,7 @@ from . import client_mock
|
|||||||
from . import authentication
|
from . import authentication
|
||||||
from .irc_utils import capabilities
|
from .irc_utils import capabilities
|
||||||
from .irc_utils import message_parser
|
from .irc_utils import message_parser
|
||||||
|
from .exceptions import ConnectionClosed
|
||||||
from .specifications import Specifications
|
from .specifications import Specifications
|
||||||
|
|
||||||
class _IrcTestCase(unittest.TestCase):
|
class _IrcTestCase(unittest.TestCase):
|
||||||
@ -107,9 +110,23 @@ class BaseClientTestCase(_IrcTestCase):
|
|||||||
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.server.bind(('', 0)) # Bind any free port
|
self.server.bind(('', 0)) # Bind any free port
|
||||||
self.server.listen(1)
|
self.server.listen(1)
|
||||||
def acceptClient(self):
|
def acceptClient(self, tls_cert=None, tls_key=None):
|
||||||
"""Make the server accept a client connection. Blocking."""
|
"""Make the server accept a client connection. Blocking."""
|
||||||
(self.conn, addr) = self.server.accept()
|
(self.conn, addr) = self.server.accept()
|
||||||
|
if tls_cert is None and tls_key is None:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
assert tls_cert and tls_key, \
|
||||||
|
'tls_cert must be provided if and only if tls_key is.'
|
||||||
|
with tempfile.NamedTemporaryFile('at') as certfile, \
|
||||||
|
tempfile.NamedTemporaryFile('at') as keyfile:
|
||||||
|
certfile.write(tls_cert)
|
||||||
|
certfile.seek(0)
|
||||||
|
keyfile.write(tls_key)
|
||||||
|
keyfile.seek(0)
|
||||||
|
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||||
|
context.load_cert_chain(certfile=certfile.name, keyfile=keyfile.name)
|
||||||
|
self.conn = context.wrap_socket(self.conn, server_side=True)
|
||||||
self.conn_file = self.conn.makefile(newline='\r\n',
|
self.conn_file = self.conn.makefile(newline='\r\n',
|
||||||
encoding='utf8')
|
encoding='utf8')
|
||||||
|
|
||||||
@ -127,6 +144,8 @@ class BaseClientTestCase(_IrcTestCase):
|
|||||||
and returns this message."""
|
and returns this message."""
|
||||||
while True:
|
while True:
|
||||||
line = self.getLine(*args)
|
line = self.getLine(*args)
|
||||||
|
if not line:
|
||||||
|
raise ConnectionClosed()
|
||||||
msg = message_parser.parse_message(line)
|
msg = message_parser.parse_message(line)
|
||||||
if not filter_pred or filter_pred(msg):
|
if not filter_pred or filter_pred(msg):
|
||||||
return msg
|
return msg
|
||||||
@ -141,12 +160,13 @@ class BaseClientTestCase(_IrcTestCase):
|
|||||||
|
|
||||||
class ClientNegociationHelper:
|
class ClientNegociationHelper:
|
||||||
"""Helper class for tests handling capabilities negociation."""
|
"""Helper class for tests handling capabilities negociation."""
|
||||||
def readCapLs(self, auth=None):
|
def readCapLs(self, auth=None, tls_config=None):
|
||||||
(hostname, port) = self.server.getsockname()
|
(hostname, port) = self.server.getsockname()
|
||||||
self.controller.run(
|
self.controller.run(
|
||||||
hostname=hostname,
|
hostname=hostname,
|
||||||
port=port,
|
port=port,
|
||||||
auth=auth,
|
auth=auth,
|
||||||
|
tls_config=tls_config,
|
||||||
)
|
)
|
||||||
self.acceptClient()
|
self.acceptClient()
|
||||||
m = self.getMessage()
|
m = self.getMessage()
|
||||||
|
@ -2,13 +2,7 @@ import ssl
|
|||||||
import time
|
import time
|
||||||
import socket
|
import socket
|
||||||
from .irc_utils import message_parser
|
from .irc_utils import message_parser
|
||||||
|
from .exceptions import NoMessageException, ConnectionClosed
|
||||||
|
|
||||||
class NoMessageException(AssertionError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ConnectionClosed(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ClientMock:
|
class ClientMock:
|
||||||
def __init__(self, name, show_io):
|
def __init__(self, name, show_io):
|
||||||
|
143
irctest/client_tests/test_tls.py
Normal file
143
irctest/client_tests/test_tls.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
from irctest import tls
|
||||||
|
from irctest import cases
|
||||||
|
from irctest.exceptions import ConnectionClosed
|
||||||
|
from irctest.irc_utils.message_parser import Message
|
||||||
|
|
||||||
|
BAD_CERT = """
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDXTCCAkWgAwIBAgIJAOd2PGU3RNwhMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||||
|
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||||
|
aWRnaXRzIFB0eSBMdGQwHhcNMTYwNzIwMDg0NjIwWhcNMTYwODE5MDg0NjIwWjBF
|
||||||
|
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||||
|
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||||
|
CgKCAQEAqo1Xu+f7UmdtNPTNPLxfILf9j/kGNNHkfqVjMHXc9rNL+JoMQ3eTdy7x
|
||||||
|
BqrWmiCHNOBAeES9anF+2SAd0LiOD2gO6h8R/+s9ftNCmZJa6kCGLX1uf5rp85aD
|
||||||
|
YbqbalgQS6PtRQZHU7+XOtW/YOolpG/2omgQmZMLyEQKNseQ4VQnuIYZoJRmXLsK
|
||||||
|
eyLgWNbpz0CsLljEziTsOLYnX9n8T469+EWgFQIvWpd/jirNTSPGTc3HVRs9g7dy
|
||||||
|
fZNi7b0jjb0qhDCOR0Kvyl9I0ANz4uEX+z/ZYfsZFU4xV7vxrDNp4gSAu8bW5JQy
|
||||||
|
/jJOsGL/9pXthCsXxY0S/6PQK70DOQIDAQABo1AwTjAdBgNVHQ4EFgQUME3YXimi
|
||||||
|
RNBg6V0SWY/417o/2zIwHwYDVR0jBBgwFoAUME3YXimiRNBg6V0SWY/417o/2zIw
|
||||||
|
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAPljmzqGfc4wcdkTFSSBg
|
||||||
|
BQzq/nUn16cTtRYaOOxAxCK4VFWY9MxxlcVlDUx1VtUPBJaUNqJ+xdIIdwBOH3O/
|
||||||
|
jwDIQMRVlXwolTZvXw/xoatpb20644bltvftJ+6TpXY6z673+5Pu7b8FjNpZd/qs
|
||||||
|
5MGsgkAGkNN6hVvOqVASMqaO5vv7UgrL1Dh4R//ADBhonBwEP4Ykz+Y8gDVXlfSx
|
||||||
|
ak4YDQfuB2+M8Y3Y9PgKNZclYEacXwV/ZIxfm7vkOPlKOEeyi9+PzCEJINWnoE08
|
||||||
|
HNsJTz9ijzsHiac6Xw07FwOBQ/3LRngfcgEOqS6W8vTC4vCkWb88mbLI4CUwi+n7
|
||||||
|
dw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
"""
|
||||||
|
BAD_KEY = """
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqjVe75/tSZ200
|
||||||
|
9M08vF8gt/2P+QY00eR+pWMwddz2s0v4mgxDd5N3LvEGqtaaIIc04EB4RL1qcX7Z
|
||||||
|
IB3QuI4PaA7qHxH/6z1+00KZklrqQIYtfW5/munzloNhuptqWBBLo+1FBkdTv5c6
|
||||||
|
1b9g6iWkb/aiaBCZkwvIRAo2x5DhVCe4hhmglGZcuwp7IuBY1unPQKwuWMTOJOw4
|
||||||
|
tidf2fxPjr34RaAVAi9al3+OKs1NI8ZNzcdVGz2Dt3J9k2LtvSONvSqEMI5HQq/K
|
||||||
|
X0jQA3Pi4Rf7P9lh+xkVTjFXu/GsM2niBIC7xtbklDL+Mk6wYv/2le2EKxfFjRL/
|
||||||
|
o9ArvQM5AgMBAAECggEAPwbqxDMvij1Uezx4WBiY4wN7fegeJgjm8vJ1nGQCG10Z
|
||||||
|
Fy7+lzQqV+IOClO56M1aiezRhmCIyzxUDzMyMX7yaLkgwd5njXbGjAbQVuZiGK1t
|
||||||
|
qIPxANEj4fPea5BFfOA8bWeP+HEgjM+BuKljBxKghIsnzs68S7SupvyV9bZ8UPho
|
||||||
|
uGZdgFfwzJlYTrjuZg1xz3KSsjDC/MrTQ3QldYlqMLjFooZH74j+vh/HAesEUu+E
|
||||||
|
aNMw0sAYi70F5xqAjLjEdNxKz05fGEkh1PPeohe2hF+vCDMMf/Si2PIbA44Z1Sod
|
||||||
|
0cFCE1zQhuJ1yOLQJwQ7wgEh9/Zz+M4L2BLB7P5OPQKBgQDgu1I1kqv/1EGTd36v
|
||||||
|
IQbYr1MVLzqWVXCTd7wdOcWIO538veQ/n/ED183I7xDt3GCBvXIwdoC0e4C9ZCAl
|
||||||
|
mjFUAawWDeQ0Ficbop51v1R/b/iAxQaIq1StUKrahZO0jjyH96CHISSUNlEWoRE3
|
||||||
|
Zh9F+PQ7tz77swn+q4oTeiUcBwKBgQDCSDVBZHO5mUTeVlyA+G93l/AwRxihWnGl
|
||||||
|
5yF/ybqxrf27MywhN7fhZCvNtcYfWTbJOh6fwnzcj0YcrPQFJ2QYt9R+tSLhkXPs
|
||||||
|
X5aXHH9MQ+lItUQ0rmSv2D8MpIulwmUpZIoCKMs17Pb81EU4NSFwa2eJmdezAyHW
|
||||||
|
T9LlQReWvwKBgDqbP0YvWOGftfZCLGx5fXKWzmDw7yNzZqdei1VH0qbDfWEDGHor
|
||||||
|
OMxaxBTJm62cUiKjiBrxXIE00A8UBHop6wFQalNaDhAzUsGXOCHW4q9VQQY724da
|
||||||
|
vvtv1Q6l1S46Bbkjr95tmz93ps/y8y1yWWeDFBZapHc5arrae2i26uSTAoGACEhf
|
||||||
|
zNvleyInp3rzEqSEzAp0OPqu+CIM+k+yQ+prxStvx81Usk3XzwogO/Ll8WwyQ73w
|
||||||
|
lEsMW7LYAFz3Qkj9oXgk3QoH5Kn40Tj6CJM0ciHrDih8MerFbCHB/l39fiGdgnhA
|
||||||
|
0fq/PxtNJFZAZTcOp+ZMUbd3VLBrfuGEUjXGNa0CgYEAqtwfoXxUIPWfZ7ezNX2m
|
||||||
|
Cbnl6JGjjYoDgohr8lHcpIc+dVChLopHayUxECWIU03Todlrn2/KNwjUKtovSsty
|
||||||
|
h4WuPDAI4yh24GjaCZYGR5xcqPCy5CNjMLxdA7HsP+Gcr3eY5XS7noBrbC6IaA0j
|
||||||
|
9E+dB63zMDFOnC4UVg5rD28=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
"""
|
||||||
|
|
||||||
|
GOOD_FINGERPRINT = 'E1EE6DE2DBC0D43E3B60407B5EE389AEC9D2C53178E0FB14CD51C3DFD544AA2B'
|
||||||
|
GOOD_CERT = """
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDXTCCAkWgAwIBAgIJAKtD9XMC1R0vMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||||
|
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||||
|
aWRnaXRzIFB0eSBMdGQwHhcNMTYwNzIwMDg0NjU0WhcNMTYwODE5MDg0NjU0WjBF
|
||||||
|
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||||
|
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||||
|
CgKCAQEA0CZDv/ny3caI0a2r7P9qH3eyPYxd+Vz5i6YzCrVIqpq9PeWL9zf9IQoM
|
||||||
|
4TAOMS9VQOCq3HsSm0YKRC9tYflmBb03rriUExsFyd4CgAqKjYNJDrTWX23j+g5T
|
||||||
|
KHF+gYhQlIljQcvX1JVMHThS1nYCz6tnbBUsKrncW9LxnR0PydL+i8jS2SkPhe/z
|
||||||
|
t/VfWsTigSzz7xVEA54ow4sYbXVx1D6CNsjccTq/hfbRGkBWvYDZt7s/bj2h445Y
|
||||||
|
B1uVuIQygySkwGQMnNALZMUhiAsuCyV7PNNleGbIPUd0LExD6OQPVchof+tdiXq7
|
||||||
|
ndLsVv6Ufh1DhPDXtn9891sOkoj2cQIDAQABo1AwTjAdBgNVHQ4EFgQUtsTGgJ3E
|
||||||
|
rRxqF0doikKnpvDr/dswHwYDVR0jBBgwFoAUtsTGgJ3ErRxqF0doikKnpvDr/dsw
|
||||||
|
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAWT2/0/ONY6XflNqGvn0i
|
||||||
|
XfB72FKIttuxMPiFKoV4czD2JWFZJ6eSTS+9NOUFPOzJfakl/F3a5Vy41hAF35o3
|
||||||
|
9N0jQt1ixkxi/BPEW2Twst4smnYgKHS4Lke8/EPn2gemxKEz7lpwICR/bFgOFIR5
|
||||||
|
OvQ2HQ+16yi8TsbB3QTUyVuixhYawlOpTtmDg9hho74+VA1oJ5bpx2maS2OTH35O
|
||||||
|
C458H4VAVNxtOIZF/zUhD8TEuTIElZtzJpghB9MdblaV8vs1fe2+ZWMXzSKOKj12
|
||||||
|
nGGz249IcunUMzjOzk6w7sVSZRWkwtwov5DsyaeW2+raig+NfF7sLECI57GWakVJ
|
||||||
|
Pg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
"""
|
||||||
|
GOOD_KEY = """
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDQJkO/+fLdxojR
|
||||||
|
ravs/2ofd7I9jF35XPmLpjMKtUiqmr095Yv3N/0hCgzhMA4xL1VA4KrcexKbRgpE
|
||||||
|
L21h+WYFvTeuuJQTGwXJ3gKACoqNg0kOtNZfbeP6DlMocX6BiFCUiWNBy9fUlUwd
|
||||||
|
OFLWdgLPq2dsFSwqudxb0vGdHQ/J0v6LyNLZKQ+F7/O39V9axOKBLPPvFUQDnijD
|
||||||
|
ixhtdXHUPoI2yNxxOr+F9tEaQFa9gNm3uz9uPaHjjlgHW5W4hDKDJKTAZAyc0Atk
|
||||||
|
xSGICy4LJXs802V4Zsg9R3QsTEPo5A9VyGh/612Jerud0uxW/pR+HUOE8Ne2f3z3
|
||||||
|
Ww6SiPZxAgMBAAECggEAMeb6lyv1bfYLFznr3gXeC21G7jqYzQ/dQ/20fvy3Ty+J
|
||||||
|
7yz5QWvK5ADk1ZgPzvrqFYPHctSOwWspSu+T6clBDF8w2lKmLW5tFNiFAO2GCidP
|
||||||
|
fJceTgKqhWipxyhui9+Cchn+Eegs9mpUtSyrr37bba5KPT9WN2gXzGvmQSSWhGwC
|
||||||
|
ewrJjh+HBpS3B006kqD9kOdgJYlmTayOaqD9WOH/ppFY8zNopEx27qqEph6WOA7W
|
||||||
|
84oUqm4JNabyXz7tRa/YsBUUqKmlBgxp0sKu5NttBPUi1+LpumjWIRj6M85NHliK
|
||||||
|
lCJgEkNriXMQ7joS0n0ZK+1cuKNr7hiGKwDoNUsfgQKBgQD0uB8KAgIjkgA+FRpr
|
||||||
|
cIQ35INPdkN8HkzZdg19nrQTwuh2Jo4SSbfm57KwyZBMnP2kHP6CMZNCycVXXj+r
|
||||||
|
1jo5ZFdAyz+MgUdTmTBXV/wH1YS6Cbp4KOv64eYT3/3cGUE5aBG0U5CqNaYq0XT7
|
||||||
|
CxPiF+pDRVDDQk+rBFz9gCKeWwKBgQDZvpd2DkVWvL0sk6pu9taPutKN145USzOn
|
||||||
|
j3SceLzL8Lu5nEfkW9O9EG0APVf8M7iq4JYF5Yzam94/pbLpSZHzYuEgNt1ee7TG
|
||||||
|
7cnxsKxQ9PDrvbElJGx0j0XRwG/CU3RJeDDmaUyosKjcYMhJujDk05Vm3RTLsii2
|
||||||
|
QiCvu4jwIwKBgQCXbl/2p2t/a1cvE4v3s/Z9R7BhuYLlCTLw1fZfJ5ezKscCZbVA
|
||||||
|
Z9Ge1v1iHDho0DS8Gxz6n4bKq2SsPawUv0nkPc0oUR0P6ueiOYcKZW2Vw3CQVnjG
|
||||||
|
5juwUZ0360GBszcDOPzLo3I/gVdD470Jo784Byh1XC0vxpbZ8qdATswdRQKBgDad
|
||||||
|
XXQZBD9LO8/QgfEvLIYEgAdfx61Q53Xhv4f3qLMmgI9/qXCXr7Y+RnjG6iix+GGz
|
||||||
|
zy1PdFLowYgJUaS99UOsy3a/DCtEsAUtY3ehrrbnmP4oKCR+zE04GnUP5XhCYmqD
|
||||||
|
IRDJ3JZ7KP+Nru7/KoBaqaCRV0P4PcnpMDWjvictAoGAWTFD2h/tsSWyHN2OyyBG
|
||||||
|
wmfusGVYB23RgQzXiLdlZOwWHZGON9dKEc9Pq6ddRArO01ewAKkcfieaLLpgb67C
|
||||||
|
Sw3oB/NsbUMkKze1zwXs9e2vcPt42vnRuQ75jU7Pb9p2NHpAdA4K/3CV00QzGA+e
|
||||||
|
El9iqRlAhgqaXc4Iz/Zxxhs=
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
|
"""
|
||||||
|
|
||||||
|
class TlsTestCase(cases.BaseClientTestCase):
|
||||||
|
def testTrustedCertificate(self):
|
||||||
|
tls_config = tls.TlsConfig(
|
||||||
|
enable=True,
|
||||||
|
trusted_fingerprints=[GOOD_FINGERPRINT])
|
||||||
|
(hostname, port) = self.server.getsockname()
|
||||||
|
self.controller.run(
|
||||||
|
hostname=hostname,
|
||||||
|
port=port,
|
||||||
|
auth=None,
|
||||||
|
tls_config=tls_config,
|
||||||
|
)
|
||||||
|
self.acceptClient(tls_cert=GOOD_CERT, tls_key=GOOD_KEY)
|
||||||
|
m = self.getMessage()
|
||||||
|
|
||||||
|
def testUntrustedCertificate(self):
|
||||||
|
tls_config = tls.TlsConfig(
|
||||||
|
enable=True,
|
||||||
|
trusted_fingerprints=[GOOD_FINGERPRINT])
|
||||||
|
(hostname, port) = self.server.getsockname()
|
||||||
|
self.controller.run(
|
||||||
|
hostname=hostname,
|
||||||
|
port=port,
|
||||||
|
auth=None,
|
||||||
|
tls_config=tls_config,
|
||||||
|
)
|
||||||
|
self.acceptClient(tls_cert=BAD_CERT, tls_key=BAD_KEY)
|
||||||
|
with self.assertRaises(ConnectionClosed):
|
||||||
|
m = self.getMessage()
|
@ -2,6 +2,7 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from irctest import authentication
|
from irctest import authentication
|
||||||
|
from irctest.basecontrollers import NotImplementedByController
|
||||||
from irctest.basecontrollers import BaseClientController, DirectoryBasedController
|
from irctest.basecontrollers import BaseClientController, DirectoryBasedController
|
||||||
|
|
||||||
TEMPLATE_CONFIG = """
|
TEMPLATE_CONFIG = """
|
||||||
@ -9,9 +10,14 @@ supybot.directories.conf: {directory}/conf
|
|||||||
supybot.directories.data: {directory}/data
|
supybot.directories.data: {directory}/data
|
||||||
supybot.directories.migrations: {directory}/migrations
|
supybot.directories.migrations: {directory}/migrations
|
||||||
supybot.log.stdout.level: {loglevel}
|
supybot.log.stdout.level: {loglevel}
|
||||||
|
|
||||||
supybot.networks: testnet
|
supybot.networks: testnet
|
||||||
supybot.networks.testnet.servers: {hostname}:{port}
|
supybot.networks.testnet.servers: {hostname}:{port}
|
||||||
supybot.networks.testnet.ssl: False
|
|
||||||
|
supybot.protocols.ssl.verifyCertificates: True
|
||||||
|
supybot.networks.testnet.ssl: {enable_tls}
|
||||||
|
supybot.networks.testnet.ssl.serverFingerprints: {trusted_fingerprints}
|
||||||
|
|
||||||
supybot.networks.testnet.sasl.username: {username}
|
supybot.networks.testnet.sasl.username: {username}
|
||||||
supybot.networks.testnet.sasl.password: {password}
|
supybot.networks.testnet.sasl.password: {password}
|
||||||
supybot.networks.testnet.sasl.ecdsa_key: {directory}/ecdsa_key.pem
|
supybot.networks.testnet.sasl.ecdsa_key: {directory}/ecdsa_key.pem
|
||||||
@ -30,7 +36,7 @@ class LimnoriaController(BaseClientController, DirectoryBasedController):
|
|||||||
with self.open_file('conf/users.conf'):
|
with self.open_file('conf/users.conf'):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self, hostname, port, auth):
|
def run(self, hostname, port, auth, tls_config):
|
||||||
# Runs a client with the config given as arguments
|
# Runs a client with the config given as arguments
|
||||||
assert self.proc is None
|
assert self.proc is None
|
||||||
self.create_config()
|
self.create_config()
|
||||||
@ -51,6 +57,8 @@ class LimnoriaController(BaseClientController, DirectoryBasedController):
|
|||||||
username=auth.username if auth else '',
|
username=auth.username if auth else '',
|
||||||
password=auth.password if auth else '',
|
password=auth.password if auth else '',
|
||||||
mechanisms=mechanisms.lower(),
|
mechanisms=mechanisms.lower(),
|
||||||
|
enable_tls=tls_config.enable if tls_config else 'False',
|
||||||
|
trusted_fingerprints=' '.join(tls_config.trusted_fingerprints) if tls_config else '',
|
||||||
))
|
))
|
||||||
self.proc = subprocess.Popen(['supybot',
|
self.proc = subprocess.Popen(['supybot',
|
||||||
os.path.join(self.directory, 'bot.conf')])
|
os.path.join(self.directory, 'bot.conf')])
|
||||||
|
@ -3,6 +3,7 @@ import tempfile
|
|||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from irctest.basecontrollers import BaseClientController
|
from irctest.basecontrollers import BaseClientController
|
||||||
|
from irctest.basecontrollers import NotImplementedByController
|
||||||
|
|
||||||
TEMPLATE_CONFIG = """
|
TEMPLATE_CONFIG = """
|
||||||
[core]
|
[core]
|
||||||
@ -45,8 +46,11 @@ class SopelController(BaseClientController):
|
|||||||
with self.open_file(self.filename) as fd:
|
with self.open_file(self.filename) as fd:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self, hostname, port, auth):
|
def run(self, hostname, port, auth, tls_config):
|
||||||
# Runs a client with the config given as arguments
|
# Runs a client with the config given as arguments
|
||||||
|
if tls_config is not None:
|
||||||
|
raise NotImplementedByController(
|
||||||
|
'TLS configuration')
|
||||||
assert self.proc is None
|
assert self.proc is None
|
||||||
self.create_config()
|
self.create_config()
|
||||||
with self.open_file(self.filename) as fd:
|
with self.open_file(self.filename) as fd:
|
||||||
|
6
irctest/exceptions.py
Normal file
6
irctest/exceptions.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class NoMessageException(AssertionError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ConnectionClosed(Exception):
|
||||||
|
pass
|
||||||
|
|
@ -36,7 +36,7 @@ def parse_message(s):
|
|||||||
http://tools.ietf.org/html/rfc1459#section-2.3.1
|
http://tools.ietf.org/html/rfc1459#section-2.3.1
|
||||||
and
|
and
|
||||||
http://ircv3.net/specs/core/message-tags-3.2.html"""
|
http://ircv3.net/specs/core/message-tags-3.2.html"""
|
||||||
assert s.endswith('\r\n'), 'Message does not end with CR LF'
|
assert s.endswith('\r\n'), 'Message does not end with CR LF: {!r}'.format(s)
|
||||||
s = s[0:-2]
|
s = s[0:-2]
|
||||||
if s.startswith('@'):
|
if s.startswith('@'):
|
||||||
(tags, s) = s.split(' ', 1)
|
(tags, s) = s.split(' ', 1)
|
||||||
|
4
irctest/tls.py
Normal file
4
irctest/tls.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import collections
|
||||||
|
|
||||||
|
TlsConfig = collections.namedtuple('TlsConfig',
|
||||||
|
'enable trusted_fingerprints')
|
Reference in New Issue
Block a user