|
| 1 | +import asyncio |
| 2 | +import base64 |
| 3 | +import logging |
| 4 | + |
| 5 | +from cloudbot import hook |
| 6 | + |
| 7 | +logger = logging.getLogger("cloudbot") |
| 8 | + |
| 9 | + |
| 10 | +@hook.on_cap_available("sasl") |
| 11 | +def sasl_available(): |
| 12 | + pass |
| 13 | + |
| 14 | + |
| 15 | +@asyncio.coroutine |
| 16 | +@hook.on_cap_ack("sasl") |
| 17 | +def sasl_ack(conn): |
| 18 | + sasl_auth = conn.config.get('sasl') |
| 19 | + if sasl_auth: |
| 20 | + sasl_mech = sasl_auth.get("mechanism", "PLAIN").upper() |
| 21 | + auth_fut = conn.loop.create_future() |
| 22 | + conn.memory["sasl_auth_future"] = auth_fut |
| 23 | + conn.cmd("AUTHENTICATE", sasl_mech) |
| 24 | + cmd, arg = yield from auth_fut |
| 25 | + if cmd == "908": |
| 26 | + logger.warning("[%s|sasl] SASL mechanism not supported", conn.name) |
| 27 | + elif cmd == "AUTHENTICATE" and arg[0] == '+': |
| 28 | + num_fut = conn.loop.create_future() |
| 29 | + conn.memory["sasl_numeric_future"] = num_fut |
| 30 | + if sasl_mech == "PLAIN": |
| 31 | + auth_str = "{nick}\0{user}\0{passwd}".format( |
| 32 | + nick=conn.nick, user=sasl_auth["user"], passwd=sasl_auth["pass"] |
| 33 | + ).encode() |
| 34 | + conn.cmd("AUTHENTICATE", base64.b64encode(auth_str).decode()) |
| 35 | + else: |
| 36 | + conn.cmd("AUTHENTICATE", '+') |
| 37 | + numeric = yield from num_fut |
| 38 | + if numeric == "902": |
| 39 | + logger.warning("[%s|sasl] SASL nick locked", conn.name) |
| 40 | + elif numeric == "903": |
| 41 | + logger.info("[%s|sasl] SASL auth successful", conn.name) |
| 42 | + elif numeric == "904": |
| 43 | + logger.warning("[%s|sasl] SASL auth failed", conn.name) |
| 44 | + elif numeric == "905": |
| 45 | + logger.warning("[%s|sasl] SASL auth too long", conn.name) |
| 46 | + elif numeric == "906": |
| 47 | + logger.warning("[%s|sasl] SASL auth aborted", conn.name) |
| 48 | + elif numeric == "907": |
| 49 | + logger.warning( |
| 50 | + "[%s|sasl] SASL auth already completed", conn.name |
| 51 | + ) |
| 52 | + |
| 53 | + |
| 54 | +@asyncio.coroutine |
| 55 | +@hook.irc_raw(["AUTHENTICATE", "908"]) |
| 56 | +def auth(irc_command, conn, irc_paramlist): |
| 57 | + future = conn.memory.get("sasl_auth_future") |
| 58 | + if future and not future.done(): |
| 59 | + future.set_result((irc_command, irc_paramlist)) |
| 60 | + |
| 61 | + |
| 62 | +@asyncio.coroutine |
| 63 | +@hook.irc_raw(["902", "903", "904", "905", "906", "907"]) |
| 64 | +def sasl_numerics(irc_command, conn): |
| 65 | + future = conn.memory.get("sasl_numeric_future") |
| 66 | + if future and not future.done(): |
| 67 | + future.set_result(irc_command) |
0 commit comments