mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-01 09:19:23 +01:00
Merge branch 'devel'
This commit is contained in:
commit
71fa4b941c
@ -38,6 +38,10 @@ Support for these IRCds exist, but are not tested as frequently and thoroughly.
|
|||||||
* InspIRCd 2.2 (git master) - module `inspircd`
|
* InspIRCd 2.2 (git master) - module `inspircd`
|
||||||
* IRCd-Hybrid (8.2.x / svn trunk) - module `hybrid`
|
* IRCd-Hybrid (8.2.x / svn trunk) - module `hybrid`
|
||||||
- Note: for host changing support and optimal functionality, a `service{}` block / U-line should be added for PyLink on every IRCd across your network.
|
- Note: for host changing support and optimal functionality, a `service{}` block / U-line should be added for PyLink on every IRCd across your network.
|
||||||
|
* Nefarious IRCu (2.0.0+) - module `nefarious` (*experimental*)
|
||||||
|
- Note: FAKE hosts (`+f`), account cloaks (user and oper), and hashed IP cloaks are supported. Make sure you configure PyLink to match your IRCd settings.
|
||||||
|
- Host changing for internal PyLink clients does not work. It should work for other users though.
|
||||||
|
- Usermode `+h ident@host` is not fully supported.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
|
15
classes.py
15
classes.py
@ -728,6 +728,21 @@ class Protocol():
|
|||||||
for p in self.irc.channels[channel].prefixmodes.values():
|
for p in self.irc.channels[channel].prefixmodes.values():
|
||||||
p.clear()
|
p.clear()
|
||||||
|
|
||||||
|
def _getSid(self, sname):
|
||||||
|
"""Returns the SID of a server with the given name, if present."""
|
||||||
|
name = sname.lower()
|
||||||
|
for k, v in self.irc.servers.items():
|
||||||
|
if v.name.lower() == name:
|
||||||
|
return k
|
||||||
|
else:
|
||||||
|
return sname # Fall back to given text instead of None
|
||||||
|
|
||||||
|
def _getUid(self, target):
|
||||||
|
"""Converts a nick argument to its matching UID. This differs from irc.nickToUid()
|
||||||
|
in that it returns the original text instead of None, if no matching nick is found."""
|
||||||
|
target = self.irc.nickToUid(target) or target
|
||||||
|
return target
|
||||||
|
|
||||||
### FakeIRC classes, used for test cases
|
### FakeIRC classes, used for test cases
|
||||||
|
|
||||||
class FakeIRC(Irc):
|
class FakeIRC(Irc):
|
||||||
|
@ -118,6 +118,11 @@ servers:
|
|||||||
# Separator character (used by relay)
|
# Separator character (used by relay)
|
||||||
separator: "/"
|
separator: "/"
|
||||||
|
|
||||||
|
# If enabled, this opts this network out of relay IP sharing. i.e. this network
|
||||||
|
# will not have its users' IPs sent across the relay, and it will not see any
|
||||||
|
# IPs of other networks' users.
|
||||||
|
#relay_no_ips: true
|
||||||
|
|
||||||
# Sets the max nick length for the network. It is important this is
|
# Sets the max nick length for the network. It is important this is
|
||||||
# set correctly, or PyLink might introduce a nick that is too long and
|
# set correctly, or PyLink might introduce a nick that is too long and
|
||||||
# cause netsplits!
|
# cause netsplits!
|
||||||
@ -207,6 +212,56 @@ servers:
|
|||||||
# same IRCd version.
|
# same IRCd version.
|
||||||
#mixed_link: true
|
#mixed_link: true
|
||||||
|
|
||||||
|
nefarious:
|
||||||
|
ip: 1.2.3.4
|
||||||
|
port: 45454
|
||||||
|
recvpass: "recv"
|
||||||
|
sendpass: "send"
|
||||||
|
hostname: "pylink.midnight.vpn"
|
||||||
|
|
||||||
|
# For P10, the SID and SID range options are just numbers. Make sure nothing
|
||||||
|
# else is using the range you're reserving for PyLink.
|
||||||
|
sid: 50
|
||||||
|
sidrange: "100-150"
|
||||||
|
channels: ["#lounge"]
|
||||||
|
protocol: nefarious
|
||||||
|
autoconnect: 5
|
||||||
|
maxnicklen: 15
|
||||||
|
netname: "Nefarious test server"
|
||||||
|
pingfreq: 30
|
||||||
|
|
||||||
|
# Halfop is optional in Nefarious. This should match your IRCd configuration.
|
||||||
|
use_halfop: false
|
||||||
|
|
||||||
|
# Determines whether account-based cloaks should be used (someone.users.yournet.org
|
||||||
|
# format). This should match your IRCd configuration:
|
||||||
|
# ENABLE this if HOST_HIDING_STYLE is set to either 1 or 3.
|
||||||
|
use_account_cloaks: true
|
||||||
|
|
||||||
|
# The cloak suffix to be used for account-based cloaks. This **MUST** match your
|
||||||
|
# IRCd configuration if use_account_cloaks is enabled.
|
||||||
|
cloak_suffix: "users.yournet.org"
|
||||||
|
|
||||||
|
# Determines whether account-based cloaks should be used for opers
|
||||||
|
# (someone.opers.yournet.org format). If use_account_cloaks is disabled,
|
||||||
|
# this will have no effect. This should match your IRCd configuration:
|
||||||
|
use_oper_account_cloaks: true
|
||||||
|
|
||||||
|
# The cloak suffix to be used for IRCop account-based cloaks. This **MUST** match your
|
||||||
|
# IRCd configuration if use_oper_account_cloaks is enabled.
|
||||||
|
oper_cloak_suffix: "staff.yournet.org"
|
||||||
|
|
||||||
|
# Determines whether UnrealIRCd-style hashed-host cloaks will be used.
|
||||||
|
# This should match your IRCd configuration:
|
||||||
|
# ENABLE this if HOST_HIDING_STYLE is set to either 2 or 3.
|
||||||
|
use_hashed_cloaks: true
|
||||||
|
|
||||||
|
# Determines whether extended accounts should be used for this network.
|
||||||
|
# This **MUST** match the EXTENDED_ACCOUNTS setting in your IRCd configuration.
|
||||||
|
# Disable this if you are using X3, and leave it on for any other service package
|
||||||
|
# (atheme, etc.)
|
||||||
|
use_extended_accounts: true
|
||||||
|
|
||||||
# Plugins to load (omit the .py extension)
|
# Plugins to load (omit the .py extension)
|
||||||
plugins:
|
plugins:
|
||||||
# Commands plugin: Provides core commands such as logging in, shutting down
|
# Commands plugin: Provides core commands such as logging in, shutting down
|
||||||
@ -282,7 +337,8 @@ relay:
|
|||||||
# Determines whether real IPs should be sent across the relay. You should
|
# Determines whether real IPs should be sent across the relay. You should
|
||||||
# generally have a consensus with your linked networks whether this should
|
# generally have a consensus with your linked networks whether this should
|
||||||
# be turned on. You will see other networks' user IP addresses, and they
|
# be turned on. You will see other networks' user IP addresses, and they
|
||||||
# will see yours.
|
# will see yours. Individual networks can also opt out of IP sharing
|
||||||
|
# both ways by defining "relay_no_ips: true" in their server block.
|
||||||
show_ips: false
|
show_ips: false
|
||||||
|
|
||||||
# Whether subservers should be spawned for each relay network (requires
|
# Whether subservers should be spawned for each relay network (requires
|
||||||
|
@ -289,7 +289,9 @@ def getRemoteUser(irc, remoteirc, user, spawnIfMissing=True):
|
|||||||
|
|
||||||
rsid = getRemoteSid(remoteirc, irc)
|
rsid = getRemoteSid(remoteirc, irc)
|
||||||
try:
|
try:
|
||||||
showRealIP = irc.conf['relay']['show_ips']
|
showRealIP = irc.conf['relay']['show_ips'] and not \
|
||||||
|
irc.serverdata.get('relay_no_ips') and not \
|
||||||
|
remoteirc.serverdata.get('relay_no_ips')
|
||||||
except KeyError:
|
except KeyError:
|
||||||
showRealIP = False
|
showRealIP = False
|
||||||
if showRealIP:
|
if showRealIP:
|
||||||
@ -411,7 +413,7 @@ def initializeChannel(irc, channel):
|
|||||||
# Send our users and channel modes to the other nets
|
# Send our users and channel modes to the other nets
|
||||||
log.debug('(%s) relay.initializeChannel: joining our (%s) users: %s', irc.name, remotenet, irc.channels[channel].users)
|
log.debug('(%s) relay.initializeChannel: joining our (%s) users: %s', irc.name, remotenet, irc.channels[channel].users)
|
||||||
relayJoins(irc, channel, irc.channels[channel].users, irc.channels[channel].ts)
|
relayJoins(irc, channel, irc.channels[channel].users, irc.channels[channel].ts)
|
||||||
if irc.pseudoclient.uid not in irc.channels[channel].users:
|
if irc.pseudoclient and irc.pseudoclient.uid not in irc.channels[channel].users:
|
||||||
irc.proto.join(irc.pseudoclient.uid, channel)
|
irc.proto.join(irc.pseudoclient.uid, channel)
|
||||||
|
|
||||||
def removeChannel(irc, channel):
|
def removeChannel(irc, channel):
|
||||||
|
@ -25,13 +25,6 @@ class HybridProtocol(TS6Protocol):
|
|||||||
ts = self.irc.start_ts
|
ts = self.irc.start_ts
|
||||||
|
|
||||||
f = self.irc.send
|
f = self.irc.send
|
||||||
# Valid keywords (from mostly InspIRCd's named modes):
|
|
||||||
# admin allowinvite autoop ban banexception blockcolor
|
|
||||||
# c_registered exemptchanops filter forward flood halfop history invex
|
|
||||||
# inviteonly joinflood key kicknorejoin limit moderated nickflood
|
|
||||||
# noctcp noextmsg nokick noknock nonick nonotice official-join op
|
|
||||||
# operonly opmoderated owner permanent private redirect regonly
|
|
||||||
# regmoderated secret sslonly stripcolor topiclock voice
|
|
||||||
|
|
||||||
# https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L80
|
# https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L80
|
||||||
cmodes = {
|
cmodes = {
|
||||||
@ -42,17 +35,14 @@ class HybridProtocol(TS6Protocol):
|
|||||||
# hybrid-specific modes:
|
# hybrid-specific modes:
|
||||||
'blockcolor': 'c', 'inviteonly': 'i', 'noctcp': 'C',
|
'blockcolor': 'c', 'inviteonly': 'i', 'noctcp': 'C',
|
||||||
'regmoderated': 'M', 'operonly': 'O', 'regonly': 'R',
|
'regmoderated': 'M', 'operonly': 'O', 'regonly': 'R',
|
||||||
'sslonly': 'S', 'banexception': 'e', 'paranoia': 'p',
|
'sslonly': 'S', 'banexception': 'e', 'noknock': 'p',
|
||||||
'registered': 'r', 'invex': 'I',
|
'registered': 'r', 'invex': 'I',
|
||||||
# Now, map all the ABCD type modes:
|
# Now, map all the ABCD type modes:
|
||||||
'*A': 'beI', '*B': 'k', '*C': 'l', '*D': 'cimnprstCMORS'
|
'*A': 'beI', '*B': 'k', '*C': 'l', '*D': 'cimnprstCMORS'
|
||||||
}
|
}
|
||||||
|
|
||||||
self.irc.cmodes.update(cmodes)
|
self.irc.cmodes = cmodes
|
||||||
|
|
||||||
# Same thing with umodes:
|
|
||||||
# bot callerid cloak deaf_commonchan helpop hidechans hideoper invisible oper
|
|
||||||
# regdeaf servprotect showwhois snomask u_registered u_stripcolor wallops
|
|
||||||
umodes = {
|
umodes = {
|
||||||
'oper': 'o', 'invisible': 'i', 'wallops': 'w', 'chary_locops': 'l',
|
'oper': 'o', 'invisible': 'i', 'wallops': 'w', 'chary_locops': 'l',
|
||||||
'cloak_hybrid': 'x', 'hidechans': 'p', 'regdeaf': 'R', 'deaf': 'D',
|
'cloak_hybrid': 'x', 'hidechans': 'p', 'regdeaf': 'R', 'deaf': 'D',
|
||||||
@ -66,7 +56,7 @@ class HybridProtocol(TS6Protocol):
|
|||||||
'*A': '', '*B': '', '*C': '', '*D': 'oiwlpRDgdx'
|
'*A': '', '*B': '', '*C': '', '*D': 'oiwlpRDgdx'
|
||||||
}
|
}
|
||||||
|
|
||||||
self.irc.umodes.update(umodes)
|
self.irc.umodes = umodes
|
||||||
|
|
||||||
# halfops is mandatory on Hybrid
|
# halfops is mandatory on Hybrid
|
||||||
self.irc.prefixmodes = {'o': '@', 'h': '%', 'v': '+'}
|
self.irc.prefixmodes = {'o': '@', 'h': '%', 'v': '+'}
|
||||||
|
1265
protocols/nefarious.py
Normal file
1265
protocols/nefarious.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -248,20 +248,9 @@ class TS6Protocol(TS6BaseProtocol):
|
|||||||
self.has_eob = False
|
self.has_eob = False
|
||||||
|
|
||||||
f = self.irc.send
|
f = self.irc.send
|
||||||
# Valid keywords (from mostly InspIRCd's named modes):
|
|
||||||
# admin allowinvite autoop ban banexception blockcolor
|
|
||||||
# c_registered exemptchanops filter forward flood halfop history invex
|
|
||||||
# inviteonly joinflood key kicknorejoin limit moderated nickflood
|
|
||||||
# noctcp noextmsg nokick noknock nonick nonotice official-join op
|
|
||||||
# operonly opmoderated owner permanent private redirect regonly
|
|
||||||
# regmoderated secret sslonly stripcolor topiclock voice
|
|
||||||
|
|
||||||
# https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L80
|
# https://github.com/grawity/irc-docs/blob/master/server/ts6.txt#L80
|
||||||
chary_cmodes = { # TS6 generic modes:
|
chary_cmodes = { # TS6 generic modes (note that +p is noknock instead of private):
|
||||||
# Note: charybdis +p has the effect of being both
|
|
||||||
# noknock AND private. Surprisingly, mapping it twice
|
|
||||||
# works pretty well: setting +p on a charybdis relay
|
|
||||||
# server sets +pK on an InspIRCd network.
|
|
||||||
'op': 'o', 'voice': 'v', 'ban': 'b', 'key': 'k', 'limit':
|
'op': 'o', 'voice': 'v', 'ban': 'b', 'key': 'k', 'limit':
|
||||||
'l', 'moderated': 'm', 'noextmsg': 'n', 'noknock': 'p',
|
'l', 'moderated': 'm', 'noextmsg': 'n', 'noknock': 'p',
|
||||||
'secret': 's', 'topiclock': 't',
|
'secret': 's', 'topiclock': 't',
|
||||||
@ -274,7 +263,7 @@ class TS6Protocol(TS6BaseProtocol):
|
|||||||
'operonly': 'O', 'adminonly': 'A', 'sslonly': 'S',
|
'operonly': 'O', 'adminonly': 'A', 'sslonly': 'S',
|
||||||
'nonotice': 'T',
|
'nonotice': 'T',
|
||||||
# Now, map all the ABCD type modes:
|
# Now, map all the ABCD type modes:
|
||||||
'*A': 'beIq', '*B': 'k', '*C': 'l', '*D': 'mnprst'}
|
'*A': 'beIq', '*B': 'k', '*C': 'lfj', '*D': 'mnprstFLPQcgzCOAST'}
|
||||||
|
|
||||||
if self.irc.serverdata.get('use_owner'):
|
if self.irc.serverdata.get('use_owner'):
|
||||||
chary_cmodes['owner'] = 'y'
|
chary_cmodes['owner'] = 'y'
|
||||||
@ -286,18 +275,17 @@ class TS6Protocol(TS6BaseProtocol):
|
|||||||
chary_cmodes['halfop'] = 'h'
|
chary_cmodes['halfop'] = 'h'
|
||||||
self.irc.prefixmodes['h'] = '%'
|
self.irc.prefixmodes['h'] = '%'
|
||||||
|
|
||||||
self.irc.cmodes.update(chary_cmodes)
|
self.irc.cmodes = chary_cmodes
|
||||||
|
|
||||||
# Same thing with umodes:
|
# Define supported user modes
|
||||||
# bot callerid cloak deaf_commonchan helpop hidechans hideoper invisible oper regdeaf servprotect showwhois snomask u_registered u_stripcolor wallops
|
|
||||||
chary_umodes = {'deaf': 'D', 'servprotect': 'S', 'u_admin': 'a',
|
chary_umodes = {'deaf': 'D', 'servprotect': 'S', 'u_admin': 'a',
|
||||||
'invisible': 'i', 'oper': 'o', 'wallops': 'w',
|
'invisible': 'i', 'oper': 'o', 'wallops': 'w',
|
||||||
'snomask': 's', 'u_noforward': 'Q', 'regdeaf': 'R',
|
'snomask': 's', 'u_noforward': 'Q', 'regdeaf': 'R',
|
||||||
'callerid': 'g', 'chary_operwall': 'z', 'chary_locops':
|
'callerid': 'g', 'chary_operwall': 'z', 'chary_locops':
|
||||||
'l', 'cloak': 'x',
|
'l', 'cloak': 'x',
|
||||||
# Now, map all the ABCD type modes:
|
# Now, map all the ABCD type modes:
|
||||||
'*A': '', '*B': '', '*C': '', '*D': 'DSaiowsQRgzl'}
|
'*A': '', '*B': '', '*C': '', '*D': 'DSaiowsQRgzlx'}
|
||||||
self.irc.umodes.update(chary_umodes)
|
self.irc.umodes = chary_umodes
|
||||||
|
|
||||||
# Toggles support of shadowircd/elemental-ircd specific channel modes:
|
# Toggles support of shadowircd/elemental-ircd specific channel modes:
|
||||||
# +T (no notice), +u (hidden ban list), +E (no kicks), +J (blocks kickrejoin),
|
# +T (no notice), +u (hidden ban list), +E (no kicks), +J (blocks kickrejoin),
|
||||||
@ -308,6 +296,7 @@ class TS6Protocol(TS6BaseProtocol):
|
|||||||
'kicknorejoin': 'J', 'repeat': 'K', 'nonick': 'd'}
|
'kicknorejoin': 'J', 'repeat': 'K', 'nonick': 'd'}
|
||||||
self.irc.cmodes.update(elemental_cmodes)
|
self.irc.cmodes.update(elemental_cmodes)
|
||||||
self.irc.cmodes['*D'] += ''.join(elemental_cmodes.values())
|
self.irc.cmodes['*D'] += ''.join(elemental_cmodes.values())
|
||||||
|
|
||||||
elemental_umodes = {'u_noctcp': 'C', 'deaf': 'D', 'bot': 'B', 'u_noinvite': 'V',
|
elemental_umodes = {'u_noctcp': 'C', 'deaf': 'D', 'bot': 'B', 'u_noinvite': 'V',
|
||||||
'hidechans': 'I'}
|
'hidechans': 'I'}
|
||||||
self.irc.umodes.update(elemental_umodes)
|
self.irc.umodes.update(elemental_umodes)
|
||||||
|
@ -35,24 +35,6 @@ class TS6BaseProtocol(Protocol):
|
|||||||
args[0] = args[0].split(':', 1)[1]
|
args[0] = args[0].split(':', 1)[1]
|
||||||
return args
|
return args
|
||||||
|
|
||||||
def _getSid(self, sname):
|
|
||||||
"""Returns the SID of a server with the given name, if present."""
|
|
||||||
name = sname.lower()
|
|
||||||
for k, v in self.irc.servers.items():
|
|
||||||
if v.name.lower() == name:
|
|
||||||
return k
|
|
||||||
else:
|
|
||||||
return sname # Fall back to given text instead of None
|
|
||||||
|
|
||||||
def _getUid(self, target):
|
|
||||||
"""Converts a nick argument to its matching UID. This differs from irc.nickToUid()
|
|
||||||
in that it returns the original text instead of None, if no matching nick is found."""
|
|
||||||
target = self.irc.nickToUid(target) or target
|
|
||||||
if target not in self.irc.users and not utils.isChannel(target):
|
|
||||||
log.debug("(%s) Possible desync? Got command target %s, who "
|
|
||||||
"isn't in our user list!", self.irc.name, target)
|
|
||||||
return target
|
|
||||||
|
|
||||||
def _getOutgoingNick(self, uid):
|
def _getOutgoingNick(self, uid):
|
||||||
"""
|
"""
|
||||||
Returns the outgoing nick for the given UID. In the base ts6_common implementation,
|
Returns the outgoing nick for the given UID. In the base ts6_common implementation,
|
||||||
|
Loading…
Reference in New Issue
Block a user