From 8341667bdd4e47d0ca14089038d299fad49a365b Mon Sep 17 00:00:00 2001 From: James Lu Date: Sun, 7 Aug 2016 15:16:37 -0700 Subject: [PATCH 1/5] relay: convert / to . in hostnames on hybrid Also, switch this check to a whitelist instead of a blacklist for better compatibility. (cherry picked from commit 990f24938b765f29d0674888c5ac09f155fc5609) --- plugins/relay.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/relay.py b/plugins/relay.py index 90df2d5..27f1692 100644 --- a/plugins/relay.py +++ b/plugins/relay.py @@ -180,8 +180,8 @@ def normalizeNick(irc, netname, nick, times_tagged=0, uid=''): def normalizeHost(irc, host): """Creates a normalized hostname for the given host suitable for introduction to a remote network (as a relay client).""" - if irc.protoname == 'unreal': - # UnrealIRCd doesn't allow slashes in hostnames + if irc.protoname not in ('inspircd', 'ts6', 'clientbot', 'nefarious'): + # UnrealIRCd and IRCd-Hybrid don't allow slashes in hostnames host = host.replace('/', '.') return host[:64] # Limited to 64 chars From 84daec0f07ac84ad3aae32e78b0e75d6b995a63c Mon Sep 17 00:00:00 2001 From: James Lu Date: Mon, 8 Aug 2016 16:35:10 -0700 Subject: [PATCH 2/5] unreal: fix services login tracking for UnrealIRCd 3.2 + Anope 1.8 More specifically, if the +d argument in SVS2MODE is a non-zero integer, ignore it and use the user's nick as account name instead. (cherry picked from commit 7dcabf072b7c84b269e4c2885525aad02038b434) --- protocols/unreal.py | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/protocols/unreal.py b/protocols/unreal.py index 9291f7c..ae50279 100644 --- a/protocols/unreal.py +++ b/protocols/unreal.py @@ -386,11 +386,11 @@ class UnrealProtocol(TS6BaseProtocol): # If +x is not set, update to use the person's real host. self.irc.users[uid].host = realhost - # Set the accountname if present - if ('+r', None) in parsedmodes and accountname == '0': + # Set the account name if present: if this is a number, set it to the user nick. + if ('+r', None) in parsedmodes and accountname.isdigit(): accountname = nick - if accountname != "0": + if not accountname.isdigit(): self.irc.callHooks([uid, 'CLIENT_SERVICES_LOGIN', {'text': accountname}]) return {'uid': uid, 'ts': ts, 'nick': nick, 'realhost': realhost, 'host': host, 'ident': ident, 'ip': ip} @@ -721,16 +721,33 @@ class UnrealProtocol(TS6BaseProtocol): """ Handles SVS2MODE, which sets services login information on the given target. """ + # Once again this syntax is inconsistent and poorly documented. +d sets a + # "services stamp" that some services packages use as an account name field, + # while others simply use for tracking the login time? In a nutshell: check + # for the +d argument: if it's an integer, ignore it and set accountname to + # the user's nick. Otherwise, treat the parameter as a nick. + # Logging in (with account info, atheme): # <- :NickServ SVS2MODE GL +rd GL - # Logging in (without account info, anope): + # Logging in (without account info, anope 2.0?): # <- :NickServ SVS2MODE 001WCO6YK +r + # Logging in (without account info, anope 1.8): + # Note: ignore the timestamp. + # <- :services.abc.net SVS2MODE GLolol +rd 1470696723 + # Logging out (atheme): # <- :NickServ SVS2MODE GL -r+d 0 - # Logging in to account from a different nick: + # Logging out (anope 1.8): + # <- :services.abc.net SVS2MODE GLolol -r+d 1 + + # Logging out (anope 2.0): + # <- :NickServ SVS2MODE 009EWLA03 -r + + # Logging in to account from a different nick (atheme): + # Note: no +r is being set. # <- :NickServ SVS2MODE somenick +d GL # Logging in to account from a different nick (anope): @@ -752,6 +769,11 @@ class UnrealProtocol(TS6BaseProtocol): account = self.irc.getFriendlyName(target) else: return + else: + if account.isdigit(): + # If the +d argument is a number, ignore it and set the account name to the nick. + account = self.irc.getFriendlyName(target) + elif ('-r', None) in parsedmodes: # Umode -r being set. @@ -763,7 +785,7 @@ class UnrealProtocol(TS6BaseProtocol): elif ('+d', None) in parsedmodes: # Nick identification status wasn't changed, but services account was. account = args[2] - if account == '0': # 0 means logout + if account == '0': # +d 0 means logout account = '' else: return From f7b93e474c8d80ac99ca9e47693779f58b283ee3 Mon Sep 17 00:00:00 2001 From: James Lu Date: Mon, 8 Aug 2016 17:05:28 -0700 Subject: [PATCH 3/5] unreal: request VHP capability so cloaked hosts for Unreal3.2 users are sent (cherry picked from commit 671d6d1893629fbd05b09b301aa8c134a9772c78) --- protocols/unreal.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/protocols/unreal.py b/protocols/unreal.py index ae50279..70282ae 100644 --- a/protocols/unreal.py +++ b/protocols/unreal.py @@ -323,7 +323,11 @@ class UnrealProtocol(TS6BaseProtocol): # EAUTH - Early auth? (Unreal 4 linking protocol) # NICKIP - Extends the NICK command used for introduction (for Unreal 3.2 servers) # to include user IPs. - f('PROTOCTL SJ3 NOQUIT NICKv2 VL UMODE2 PROTOCTL NICKIP EAUTH=%s SID=%s' % (self.irc.serverdata["hostname"], self.irc.sid)) + # VHP - Sends cloaked hosts of UnrealIRCd 3.2 users as the hostname. This is important + # because UnrealIRCd 3.2 only has one vHost field in its NICK command, and not two + # like UnrealIRCd 4.0 (cloaked host + displayed host). Without VHP, cloaking does + # not work for any UnrealIRCd 3.2 users. + f('PROTOCTL SJ3 NOQUIT NICKv2 VL UMODE2 PROTOCTL NICKIP EAUTH=%s SID=%s VHP' % (self.irc.serverdata["hostname"], self.irc.sid)) sdesc = self.irc.serverdata.get('serverdesc') or self.irc.botdata['serverdesc'] f('SERVER %s 1 U%s-h6e-%s :%s' % (host, self.proto_ver, self.irc.sid, sdesc)) f('NETINFO 1 %s %s * 0 0 0 :%s' % (self.irc.start_ts, self.proto_ver, self.irc.serverdata.get("netname", self.irc.name))) @@ -596,9 +600,10 @@ class UnrealProtocol(TS6BaseProtocol): # internally by their nicks. In other words, we need to convert from this: # <- NICK Global 3 1456843578 services novernet.com services.novernet.com 0 +ioS * :Global Noticer # & nick hopcount timestamp username hostname server service-identifier-token :realname - # <- NICK GL32 2 1460221959 gl localhost unreal32.midnight.vpn 0 +iowx * fwAAAQ== :realname (with NICKIP enabled) + # With NICKIP and VHP enabled: + # <- NICK GL32 2 1470699865 gl localhost unreal32.midnight.vpn GL +iowx hidden-1C620195 AAAAAAAAAAAAAAAAAAAAAQ== :realname # to this: - # <- :001 UID GL 0 1441306929 gl localhost 0018S7901 0 +iowx * midnight-1C620195 fwAAAQ== :realname + # <- :001 UID GL 0 1441306929 gl localhost 0018S7901 0 +iowx * hidden-1C620195 fwAAAQ== :realname log.debug('(%s) got legacy NICK args: %s', self.irc.name, ' '.join(args)) new_args = args[:] # Clone the old args list @@ -609,7 +614,9 @@ class UnrealProtocol(TS6BaseProtocol): self.legacy_nickcount += 1 new_args[5] = fake_uid - # Insert a fake cloaked host (just make it equal the real host, I don't care) + # This adds a dummy cloaked host (equal the real host) to put the displayed host in the + # right position. As long as the VHP capability is respected, this will propagate +x cloaked + # hosts from UnrealIRCd 3.2 users. Otherwise, +x host cloaking won't work! new_args.insert(-2, args[4]) log.debug('(%s) translating legacy NICK args to: %s', self.irc.name, ' '.join(new_args)) From 9d582661b734ad06c87db23edeb81e113ff2a757 Mon Sep 17 00:00:00 2001 From: James Lu Date: Wed, 17 Aug 2016 13:58:07 -0700 Subject: [PATCH 4/5] README: reformat, add more verbose setup guide This mentions multiple ways of installation now: via PyPI or source. Closes #310. --- README.md | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 77fb4cb..3bdc7b1 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ PyLink is an extensible, plugin-based IRC services framework written in Python. 2) a versatile framework and gateway to IRC. +PyLink and any bundled software are licensed under the Mozilla Public License, version 2.0 ([LICENSE.MPL2](LICENSE.MPL2)). The corresponding documentation in the [docs/](docs/) folder is licensed under the Creative Attribution-ShareAlike 4.0 International License. ([LICENSE.CC-BY-SA-4.0](LICENSE.CC-BY-SA-4.0)) + ## Support **First, MAKE SURE you've read the [FAQ](docs/faq.md)!** @@ -16,17 +18,35 @@ Please report any bugs you find to the [issue tracker](https://github.com/GLolol You can also find support via our IRC channels: `#PyLink @ irc.overdrivenetworks.com `([webchat](https://webchat.overdrivenetworks.com/?channels=PyLink,dev)) or `#PyLink @ chat.freenode.net`. Ask your questions and be patient for a response. -## License +## Installation -PyLink and any bundled software are licensed under the Mozilla Public License, version 2.0 ([LICENSE.MPL2](LICENSE.MPL2)). The corresponding documentation in the [docs/](docs/) folder is licensed under the Creative Attribution-ShareAlike 4.0 International License. ([LICENSE.CC-BY-SA-4.0](LICENSE.CC-BY-SA-4.0)) +### Installing from source (recommended) -## Dependencies +First, make sure the following dependencies are met: * Python 3.4+ -* Setuptools (`pip install setuptools`) -* PyYAML (`pip install pyyaml`) -* [ircmatch](https://github.com/mammon-ircd/ircmatch) (`pip install ircmatch`) -* *For the servprotect plugin*: [expiringdict](https://github.com/mailgun/expiringdict) (note: unfortunately, installation is broken in pip due to [mailgun/expiringdict#13](https://github.com/mailgun/expiringdict/issues/13)) +* Setuptools (`pip3 install setuptools`) +* PyYAML (`pip3 install pyyaml`) +* [ircmatch](https://github.com/mammon-ircd/ircmatch) (`pip3 install ircmatch`) +* *For the servprotect plugin*: [expiringdict](https://github.com/mailgun/expiringdict) (install this from source; installation is broken in pip due to [mailgun/expiringdict#13](https://github.com/mailgun/expiringdict/issues/13)) + +1) Clone the repository: `git clone https://github.com/GLolol/PyLink && cd PyLink` + +2) Install PyLink using `python3 setup.py install` (global install) or `python3 setup.py install --user` (local install) + - Note: `--user` is a *literal* string; *do not* replace it with your username. + +### Installing via PyPI +1) Make sure you're running the right pip command: on most distros, pip for Python3 uses the command `pip3`. + +2) Run `pip3 install pylinkirc` to download and install PyLink. pip will automatically resolve dependencies. + +3) Download or copy https://github.com/GLolol/PyLink/blob/master/example-conf.yml for an example configuration. + +## Configuration + +1) Rename `example-conf.yml` to `pylink.yml` (or a similarly named `.yml` file) and configure your instance there. Note that the configuration format isn't finalized yet - this means that your configuration may break in an update! + +2) Run `pylink` from the command line. PyLink will load its configuration from `pylink.yml` by default, but you can override this by running `pylink` with a config argument (e.g. `pylink mynet.yml`). ## Supported IRCds @@ -53,13 +73,3 @@ Support for these IRCds exist, but are not tested as frequently and thoroughly. - For optimal functionality (mode overrides in relay, etc.), a `UWorld{}` block / U-line should be added for every server that PyLink spawns. Other TS6 and P10 variations may work, but are not officially supported. - -## Setup - -1) Install PyLink by using `python3 setup.py install` (global install) or `python3 setup.py install --user` (local install; note: `--user` is a *literal* string) - -2) Rename `example-conf.yml` to `pylink.yml` and configure your instance there. Note that the configuration format isn't finalized yet - this means that your configuration may break in an update! - -3) Run `pylink` from the command line. - -4) Profit??? From a1e7c89027a51c6d36b136ebbea650c93eea51d9 Mon Sep 17 00:00:00 2001 From: James Lu Date: Wed, 17 Aug 2016 13:59:33 -0700 Subject: [PATCH 5/5] FAQ: update link to dependencies list --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index 7d89dd4..4923c41 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -23,4 +23,4 @@ In no particular order: PyLink does not support inbound connections - much like Atheme or Anope, it only connects outwards to IRCds. (If you don't understand what this means, it means you should turn autoconnect OFF for PyLink) ### I get errors like "ImportError: No module named 'yaml'" when I start PyLink -- You are missing dependencies - re-read https://github.com/GLolol/PyLink#dependencies \ No newline at end of file +- You are missing dependencies - re-read https://github.com/GLolol/PyLink#installing-from-source-recommended