irc: Add registration handling of new connections
patch f6adfec3b3a67fe89d7f7528ea918372f8070ace
Author: E. Bosch <presidev@AT@gmail.com>
Date: Wed Jan 27 20:51:33 CET 2021
* irc: Add registration handling of new connections
Improve replies, error responses, motd, nick validation, etc.
addfile ./include.py
hunk ./include.py 1
+
+# Constants
+
+VERSION = '0.1'
+NICK_MAX_LENGTH = 20
+CHAN_MAX_LENGHT = 50
hunk ./irc.py 6
+import string
+import time
hunk ./irc.py 14
+from include import VERSION, CHAN_MAX_LENGHT, NICK_MAX_LENGTH
+from irc_replies import irc_codes
hunk ./irc.py 17
-from irc_replies import irc_codes
+
+# Constants
+
+VALID_IRC_NICK_FIRST_CHARS = string.ascii_letters + '[]\`_^{|}'
+VALID_IRC_NICK_CHARS = VALID_IRC_NICK_FIRST_CHARS + string.digits + '-'
hunk ./irc.py 92
+ self.start_time = time.strftime('%a %d %b %Y %H:%M:%S %z')
hunk ./irc.py 102
+ # IRC handlers
+
+ async def handle_irc_pass(self, user, password):
+ self.logger.debug('Handling PASS: %s %s', password)
+
+ if user.registered:
+ await self.reply(user, 'ERR_ALREADYREGISTRED')
+ else:
+ user.recv_pass = password
+
hunk ./irc.py 115
- if user.irc_nick in self.iid_to_tid:
- tid = self.iid_to_tid[user.irc_nick]
- self.tg.tid_to_iid[tid] = nick
- self.iid_to_tid[nick] = tid
-
- user.irc_nick = nick
+ if not self.valid_nick(nick):
+ await self.reply(user, 'ERR_ERRONEUSNICKNAME')
+ elif nick in [x.irc_nick for x in self.users if x is not user]:
+ await self.reply(user, 'ERR_NICKNAMEINUSE')
+ elif user.password == user.recv_pass:
+ user.irc_nick = nick
+
+ if user.irc_nick in self.iid_to_tid:
+ tid = self.iid_to_tid[user.irc_nick]
+ self.tg.tid_to_iid[tid] = nick
+ self.iid_to_tid[nick] = tid
+
+ if not user.registered and user.irc_username:
+ user.registered = True
+ await self.send_greeting(user)
+ else:
+ await self.reply(user, 'ERR_PASSWDMISMATCH')
hunk ./irc.py 138
-
- await self.send_irc_command(user, ':{} 001 {} :{}'.format(
- self.hostname, user.irc_nick, 'Welcome to irgramd'
- ))
- await self.send_irc_command(user, ':{} 376 {} :{}'.format(
- self.hostname, user.irc_nick, 'End of MOTD command'
- ))
+ if user.irc_nick:
+ user.registered = True
+ await self.send_greeting(user)
hunk ./irc.py 147
- async def handle_irc_pass(self, user, app_id, app_hash):
- self.logger.debug('Handling PASS: %s %s', app_id, app_hash)
-
hunk ./irc.py 170
+ async def reply_param(self, user, num, rest):
+ await self.send_irc_command(user, ':{} {} {} {}'.format(
+ self.hostname, num, user.irc_nick, rest
+ ))
+
+ async def send_greeting(self, user):
+ num, rest = irc_codes['RPL_WELCOME']
+ await self.reply_param(user, num, rest.format(user.irc_nick))
+ num, rest = irc_codes['RPL_YOURHOST']
+ await self.reply_param(user, num, rest.format(self.hostname, VERSION))
+ num, rest = irc_codes['RPL_CREATED']
+ await self.reply_param(user, num, rest.format(self.start_time))
+ num, rest = irc_codes['RPL_MYINFO']
+ await self.reply_param(user, num, rest.format(self.hostname, VERSION))
+ num, rest = irc_codes['RPL_ISUPPORT']
+ await self.reply_param(user, num, rest.format(str(CHAN_MAX_LENGHT), str(NICK_MAX_LENGTH)))
+ await self.send_motd(user)
+
+ async def send_motd(self, user):
+ num, rest = irc_codes['RPL_MOTDSTART']
+ await self.reply_param(user, num, rest.format(self.hostname))
+ num, rest = irc_codes['RPL_MOTD']
+ await self.reply_param(user, num, rest.format('Welcome to the irgramd server'))
+ await self.reply_param(user, num, rest.format(''))
+ await self.reply_param(user, num, rest.format('This is not a normal IRC server, it\'s a gateway that'))
+ await self.reply_param(user, num, rest.format('allows connecting from an IRC client (the program that'))
+ await self.reply_param(user, num, rest.format('you are [probably] using right now) to the Telegram instant'))
+ await self.reply_param(user, num, rest.format('messaging network as a regular user account (not bot)'))
+ await self.reply_param(user, num, rest.format(''))
+ await self.reply_param(user, num, rest.format('irgramd is an open source project that you can find on'))
+ await self.reply_param(user, num, rest.format('git repository: https://github.com/prsai/irgramd'))
+ await self.reply_param(user, num, rest.format('darcs repository: https://src.presi.org/darcs/irgramd'))
+ await self.reply(user, 'RPL_ENDOFMOTD')
+
hunk ./irc.py 237
+ def valid_nick(self, nick):
+ if len(nick) <= NICK_MAX_LENGTH and nick[0] in VALID_IRC_NICK_FIRST_CHARS:
+ for x in nick[1:]:
+ if x not in VALID_IRC_NICK_CHARS:
+ return 0
+ return 1
+ else: return 0
+
hunk ./irc.py 253
+ self.password = ''
hunk ./irc_replies.py 4
- 'RPL_WELCOME': ('001', 'Welcome to the irgramd gateway, {}'),
- 'RPL_YOURHOST': ('002', 'Your host is {}, running version irgramd-{}'),
- 'RPL_CREATED': ('003', 'This server was created {}'),
+ 'RPL_WELCOME': ('001', ':Welcome to the irgramd gateway, {}'),
+ 'RPL_YOURHOST': ('002', ':Your host is {}, running version irgramd-{}'),
+ 'RPL_CREATED': ('003', ':This server was created {}'),
hunk ./irc_replies.py 8
- 'RPL_ISUPPORT': ('005', 'CASEMAPPING=ascii CHANLIMIT=#&+: CHANTYPES=&#+ CHANMODES=,,,nt CHANNELLEN={} NICKLEN={} SAFELIST'),
- 'RPL_MOTDSTART': ('375', '- {} Message of the day - '),
- 'RPL_MOTD': ('372', '{}'),
+ 'RPL_ISUPPORT': ('005', 'CASEMAPPING=ascii CHANLIMIT=#&+: CHANTYPES=&#+ CHANMODES=,,,nt CHANNELLEN={} NICKLEN={} SAFELIST :are supported by this server'),
+ 'RPL_MOTDSTART': ('375', ':- {} Message of the day - '),
+ 'RPL_MOTD': ('372', ':- {}'),
hunk ./telegram.py 6
+# Local modules
+
+from include import CHAN_MAX_LENGHT, NICK_MAX_LENGTH
+
hunk ./telegram.py 18
-NICK_MAX_LENGTH = 20