From 1bfe06d2ea0a80d6dc60fd011d82357d29ff1a60 Mon Sep 17 00:00:00 2001 From: jesopo Date: Sun, 19 Apr 2020 21:51:33 +0100 Subject: [PATCH] implement STS policies; we're not parsing them yet though --- ircrobots/__init__.py | 3 ++- ircrobots/bot.py | 2 +- ircrobots/ircv3.py | 20 ++++++++++++++++++-- ircrobots/params.py | 9 +++++++++ ircrobots/server.py | 10 +++++++--- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ircrobots/__init__.py b/ircrobots/__init__.py index d32d6bc..baa110b 100644 --- a/ircrobots/__init__.py +++ b/ircrobots/__init__.py @@ -1,4 +1,5 @@ from .bot import Bot from .server import Server -from .params import ConnectionParams, SASLUserPass, SASLExternal, SASLSCRAM +from .params import (ConnectionParams, SASLUserPass, SASLExternal, SASLSCRAM, + STSPolicy) from .ircv3 import Capability diff --git a/ircrobots/bot.py b/ircrobots/bot.py index a19599e..9a2634b 100644 --- a/ircrobots/bot.py +++ b/ircrobots/bot.py @@ -23,7 +23,7 @@ class Bot(object): async def add_server(self, name: str, params: ConnectionParams) -> Server: server = self.create_server(name) self.servers[name] = server - await server.connect(TCPTransport() ,params) + await server.connect(TCPTransport(), params) await self._server_queue.put(server) return server diff --git a/ircrobots/ircv3.py b/ircrobots/ircv3.py index bdb27bf..de1ea57 100644 --- a/ircrobots/ircv3.py +++ b/ircrobots/ircv3.py @@ -1,9 +1,12 @@ -from typing import Dict, Iterable, List, Optional -from irctokens import build +from time import time +from typing import Dict, Iterable, List, Optional, Tuple +from dataclasses import dataclass +from irctokens import build from .contexts import ServerContext from .matching import Response, ResponseOr, ParamAny, ParamLiteral from .interface import ICapability +from .params import STSPolicy class Capability(ICapability): def __init__(self, @@ -93,3 +96,16 @@ class CAPContext(ServerContext): async def handshake(self): await self.on_ls(self.server.available_caps) await self.server.send(build("CAP", ["END"])) + +class STSContext(ServerContext): + async def transmute(self, + port: int, + tls: bool, + sts: Optional[STSPolicy]) -> Tuple[int, bool]: + if not sts is None: + now = time() + since = (now-sts.created) + if since <= sts.duration: + return sts.port, True + + return port, tls diff --git a/ircrobots/params.py b/ircrobots/params.py index b8ddbd7..7d14688 100644 --- a/ircrobots/params.py +++ b/ircrobots/params.py @@ -20,6 +20,13 @@ class SASLExternal(SASLParams): def __init__(self): super().__init__("EXTERNAL") +@dataclass +class STSPolicy(object): + created: int + port: int + duration: int + preload: bool + @dataclass class ConnectionParams(object): nickname: str @@ -34,3 +41,5 @@ class ConnectionParams(object): password: Optional[str] = None tls_verify: bool = True sasl: Optional[SASLParams] = None + + sts: Optional[STSPolicy] = None diff --git a/ircrobots/server.py b/ircrobots/server.py index c087c5b..7cf5c97 100644 --- a/ircrobots/server.py +++ b/ircrobots/server.py @@ -7,7 +7,8 @@ from ircstates import Emit, Channel from ircstates.numerics import * from irctokens import build, Line, tokenise -from .ircv3 import CAPContext, CAP_ECHO, CAP_SASL, CAP_LABEL, LABEL_TAG +from .ircv3 import (CAPContext, STSContext, CAP_ECHO, CAP_SASL, CAP_LABEL, + LABEL_TAG) from .sasl import SASLContext, SASLResult from .join_info import WHOContext from .matching import ResponseOr, Responses, Response, ParamAny, ParamFolded @@ -80,10 +81,13 @@ class Server(IServer): async def connect(self, transport: ITCPTransport, params: ConnectionParams): + port, tls = await STSContext(self).transmute( + params.port, params.tls, params.sts) + reader, writer = await transport.connect( params.host, - params.port, - tls =params.tls, + port, + tls =tls, tls_verify=params.tls_verify, bindhost =params.bindhost)