Added support for SSL IRC connections.

This commit is contained in:
Sina Mashek 2016-03-26 02:44:20 -07:00
parent 402b9a7394
commit 2d54bc33ab
4 changed files with 31 additions and 11 deletions

View file

@ -755,7 +755,7 @@ class CmdIRC2Chan(MuxCommand):
link an evennia channel to an external IRC channel link an evennia channel to an external IRC channel
Usage: Usage:
@irc2chan[/switches] <evennia_channel> = <ircnetwork> <port> <#irchannel> <botname> @irc2chan[/switches] <evennia_channel> = <ircnetwork> <[+]port> <#irchannel> <botname>
@irc2chan/list @irc2chan/list
@irc2chan/delete botname|#dbid @irc2chan/delete botname|#dbid
@ -774,7 +774,8 @@ class CmdIRC2Chan(MuxCommand):
vice versa. The bot will automatically connect at server start, so this vice versa. The bot will automatically connect at server start, so this
comman need only be given once. The /disconnect switch will permanently comman need only be given once. The /disconnect switch will permanently
delete the bot. To only temporarily deactivate it, use the {w@services{n delete the bot. To only temporarily deactivate it, use the {w@services{n
command instead. command instead. To connect with SSL, add a plus sign (+) before the port
number.
""" """
key = "@irc2chan" key = "@irc2chan"
@ -794,10 +795,10 @@ class CmdIRC2Chan(MuxCommand):
ircbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")] ircbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
if ircbots: if ircbots:
from evennia.utils.evtable import EvTable from evennia.utils.evtable import EvTable
table = EvTable("{wdbid{n", "{wbotname{n", "{wev-channel{n", "{wirc-channel{n", maxwidth=_DEFAULT_WIDTH) table = EvTable("{wdbid{n", "{wbotname{n", "{wev-channel{n", "{wirc-channel{n", "{wSSL{n", maxwidth=_DEFAULT_WIDTH)
for ircbot in ircbots: for ircbot in ircbots:
ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel, ircbot.db.irc_network, ircbot.db.irc_port) ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel, ircbot.db.irc_network, ircbot.db.irc_port)
table.add_row(ircbot.id, ircbot.db.irc_botname, ircbot.db.ev_channel, ircinfo) table.add_row(ircbot.id, ircbot.db.irc_botname, ircbot.db.ev_channel, ircinfo, ircbot.db.irc_ssl)
self.caller.msg(table) self.caller.msg(table)
else: else:
self.msg("No irc bots found.") self.msg("No irc bots found.")
@ -820,7 +821,7 @@ class CmdIRC2Chan(MuxCommand):
return return
if not self.args or not self.rhs: if not self.args or not self.rhs:
string = "Usage: @irc2chan[/switches] <evennia_channel> = <ircnetwork> <port> <#irchannel> <botname>" string = "Usage: @irc2chan[/switches] <evennia_channel> = <ircnetwork> <[+]port> <#irchannel> <botname>"
self.msg(string) self.msg(string)
return return
@ -830,6 +831,9 @@ class CmdIRC2Chan(MuxCommand):
irc_network, irc_port, irc_channel, irc_botname = \ irc_network, irc_port, irc_channel, irc_botname = \
[part.strip() for part in self.rhs.split(None, 3)] [part.strip() for part in self.rhs.split(None, 3)]
irc_channel = "#%s" % irc_channel irc_channel = "#%s" % irc_channel
if "+" in irc_port:
irc_ssl = True
irc_port = irc_port[1:]
except Exception: except Exception:
string = "IRC bot definition '%s' is not valid." % self.rhs string = "IRC bot definition '%s' is not valid." % self.rhs
self.msg(string) self.msg(string)
@ -848,7 +852,7 @@ class CmdIRC2Chan(MuxCommand):
else: else:
bot = create.create_player(botname, None, None, typeclass=bots.IRCBot) bot = create.create_player(botname, None, None, typeclass=bots.IRCBot)
bot.start(ev_channel=channel, irc_botname=irc_botname, irc_channel=irc_channel, bot.start(ev_channel=channel, irc_botname=irc_botname, irc_channel=irc_channel,
irc_network=irc_network, irc_port=irc_port) irc_network=irc_network, irc_port=irc_port, irc_ssl=irc_ssl)
self.msg("Connection created. Starting IRC bot.") self.msg("Connection created. Starting IRC bot.")
# RSS connection # RSS connection

View file

@ -168,7 +168,7 @@ class IRCBot(Bot):
Bot for handling IRC connections. Bot for handling IRC connections.
""" """
def start(self, ev_channel=None, irc_botname=None, irc_channel=None, irc_network=None, irc_port=None): def start(self, ev_channel=None, irc_botname=None, irc_channel=None, irc_network=None, irc_port=None, irc_ssl=None):
""" """
Start by telling the portal to start a new session. Start by telling the portal to start a new session.
@ -179,6 +179,7 @@ class IRCBot(Bot):
irc_channel (str): Name of channel on the form `#channelname`. irc_channel (str): Name of channel on the form `#channelname`.
irc_network (str): URL of the IRC network, like `irc.freenode.net`. irc_network (str): URL of the IRC network, like `irc.freenode.net`.
irc_port (str): Port number of the irc network, like `6667`. irc_port (str): Port number of the irc network, like `6667`.
irc_ssl (bool): Indicates whether to use SSL connection.
""" """
global _SESSIONS global _SESSIONS
@ -206,6 +207,8 @@ class IRCBot(Bot):
self.db.irc_network = irc_network self.db.irc_network = irc_network
if irc_port: if irc_port:
self.db.irc_port = irc_port self.db.irc_port = irc_port
if irc_ssl:
self.db.irc_ssl = irc_ssl
# instruct the server and portal to create a new session with # instruct the server and portal to create a new session with
# the stored configuration # the stored configuration
@ -213,7 +216,8 @@ class IRCBot(Bot):
"botname": self.db.irc_botname, "botname": self.db.irc_botname,
"channel": self.db.irc_channel , "channel": self.db.irc_channel ,
"network": self.db.irc_network, "network": self.db.irc_network,
"port": self.db.irc_port} "port": self.db.irc_port,
"ssl": self.db.irc_ssl}
_SESSIONS.start_bot_session("evennia.server.portal.irc.IRCBotFactory", configdict) _SESSIONS.start_bot_session("evennia.server.portal.irc.IRCBotFactory", configdict)
def msg(self, text=None, **kwargs): def msg(self, text=None, **kwargs):

View file

@ -9,7 +9,7 @@ from future.utils import viewkeys
import re import re
from twisted.application import internet from twisted.application import internet
from twisted.words.protocols import irc from twisted.words.protocols import irc
from twisted.internet import protocol from twisted.internet import protocol, reactor, ssl
from evennia.server.session import Session from evennia.server.session import Session
from evennia.utils import logger, utils from evennia.utils import logger, utils
@ -230,7 +230,7 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
factor = 1.5 factor = 1.5
maxDelay = 60 maxDelay = 60
def __init__(self, sessionhandler, uid=None, botname=None, channel=None, network=None, port=None): def __init__(self, sessionhandler, uid=None, botname=None, channel=None, network=None, port=None, ssl=None):
""" """
Storing some important protocol properties. Storing some important protocol properties.
@ -243,6 +243,7 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
channel (str): IRC channel to connect to. channel (str): IRC channel to connect to.
network (str): Network address to connect to. network (str): Network address to connect to.
port (str): Port of the network. port (str): Port of the network.
ssl (bool): Indicates SSL connection.
""" """
self.sessionhandler = sessionhandler self.sessionhandler = sessionhandler
@ -251,6 +252,7 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
self.channel = str(channel) self.channel = str(channel)
self.network = str(network) self.network = str(network)
self.port = port self.port = port
self.ssl = ssl
self.bot = None self.bot = None
def buildProtocol(self, addr): def buildProtocol(self, addr):
@ -267,6 +269,7 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
protocol.channel = self.channel protocol.channel = self.channel
protocol.network = self.network protocol.network = self.network
protocol.port = self.port protocol.port = self.port
protocol.ssl = self.ssl
return protocol return protocol
def startedConnecting(self, connector): def startedConnecting(self, connector):
@ -308,5 +311,13 @@ class IRCBotFactory(protocol.ReconnectingClientFactory):
""" """
if self.port: if self.port:
service = internet.TCPClient(self.network, int(self.port), self) if ssl:
"""
Requires PyOpenSSL
"""
service = reactor.connectSSL(self.network, int(self.port), self, ssl.ClientContextFactory())
else:
service = internet.TCPClient(self.network, int(self.port), self)
self.sessionhandler.portal.services.addService(service) self.sessionhandler.portal.services.addService(service)

View file

@ -6,3 +6,4 @@ mock >= 1.0.1
pillow == 2.9.0 pillow == 2.9.0
pytz pytz
future >= 0.15.2 future >= 0.15.2
pyopenssl >= 16.0.0