Example #1
0
 def connectionMade(self):
     self.connection_expire.cancel()
     self.type = IRCUser(self)
     tryagain = []
     for function in self.factory.actions["connect"]:
         result = function(self.type)
         if result == "again":
             tryagain.append(function)
         elif not result:
             self.transport.loseConnection()
             self.type = None
             break
     if self.type:
         for function in tryagain:
             if not function(self.type):
                 self.transport.loseConnection()
                 self.type = None
                 break
     if self.type:
         self.secure = ISSLTransport(self.transport, None) is not None
         self.data_checker.start(5)
         self.pinger.start(self.factory.servconfig["client_ping_interval"], now=False)
         for server in self.factory.servers.itervalues():
             if server.nearHop == self.factory.name:
                 server.callRemote(ConnectUser, uuid=self.type.uuid, ip=self.type.ip, server=self.factory.name, secure=self.secure, signon=epoch(self.type.signon))
Example #2
0
 def handleCommand(self, command, prefix, params):
     # If we aren't waiting for auth, let them do as they please
     if self.auth_timer is None:
         IRCUser.handleCommand(self, command, prefix, params)
     # Allow some basic command, plus PRIVMSG so they can identify
     elif command in ["PING","PONG","NICK","PRIVMSG","QUIT","NS","NICKSERV","LOGIN"]:
         IRCUser.handleCommand(self, command, prefix, params)
     else:
         self.sendMessage("NOTICE", ":You can not use command \x02{}\x0F while identifying a registered nick.".format(command), prefix=self.service_prefix("NickServ"))
Example #3
0
 def irc_NICK(self, prefix, params):
     if params and irc_lower(params[0]) in self.services: # Can't use a service nick
         self.sendMessage(irc.ERR_NICKNAMEINUSE, params[0], ":Nickname is already in use", prefix=self.service_prefix("NickServ"))
         return
     oldnick = irc_lower(self.nickname)
     IRCUser.irc_NICK(self, prefix, params)
     newnick = irc_lower(self.nickname)
     if oldnick != newnick:
         self.checkNick()
Example #4
0
 def join(self, channel, key):
     IRCUser.join(self, channel, key)
     if channel in self.channels and self.nickserv_id:
         c = self.ircd.channels[channel]
         mode = self.ircd.channel_auto_ops[self.nickserv_id] if self.nickserv_id in self.ircd.channel_auto_ops else "v"
         m, b, f = c.mode.combine("+{}".format(mode),[self.nickname],c.name)
         if m: # Should always be true!?
             if not c.log.closed:
                 c.log.write("[{:02d}:{:02d}:{:02d}] {} set modes {}\n".format(now().hour, now().minute, now().second, "BidServ", m))
             for u in c.users.itervalues():
                 u.sendMessage("MODE", m, to=c.name, prefix=self.service_prefix("BidServ"))
Example #5
0
 def irc_PRIVMSG(self, prefix, params):
     # You can only PRIVMSG NickServ while identifying
     if params and self.auth_timer is not None and irc_lower(params[0]) != "nickserv":
         self.sendMessage("NOTICE", ":You can not PRIVMSG anybody but NickServ while identifying a registered nick.", prefix=self.service_prefix("NickServ"))
         return
     if len(params) > 1 and irc_lower(params[0]) in self.services:
         service = irc_lower(params[0])
         command, chaff, params = params[1].partition(" ")
         params = filter(lambda x: x, params.split(" "))
         method = getattr(self, "{}_{}".format(service, command.upper()), None)
         if method is None:
             method = getattr(self, "{}_USAGE".format(service), None)
             method(prefix, params, command)
         else:
             method(prefix, params)
     else:
         IRCUser.irc_PRIVMSG(self, prefix, params)
Example #6
0
 def __init__(self, parent, user, password, nick):
     # Service nicks are technically valid and not in use, but you can't have them.
     if irc_lower(nick) in self.services:
         parent.sendMessage(irc.ERR_NICKNAMEINUSE, nick, ":Nickname is already in use", prefix=parent.factory.server_name)
         parent.sendMessage("ERROR",":Closing Link: {}".format(nick))
         parent.transport.loseConnection()
         raise ValueError("Invalid nickname")
     IRCUser.__init__(self, parent, user, password, nick)
     self.auth_timer = None
     self.nickserv_id = None
     if password:
         if ":" in password:
             username, chaff, password = password.partition(":")
             self.auth(username, password)
         else:
             self.token(password)
     else:
         self.checkNick()
     #Auto-join #desertbus
     self.join("#desertbus",None)
Example #7
0
class IRCProtocol(irc.IRC):
    def __init__(self, ip):
        self.dead = False
        self.type = None
        self.secure = False
        self.data = 0
        self.data_checker = LoopingCall(self.checkData)
        self.pinger = LoopingCall.withCount(self.ping)
        self.connection_expire = reactor.callLater(15, self.connectionLost, None)
        self.ip = ip
    
    def connectionMade(self):
        self.connection_expire.cancel()
        self.type = IRCUser(self)
        tryagain = []
        for function in self.factory.actions["connect"]:
            result = function(self.type)
            if result == "again":
                tryagain.append(function)
            elif not result:
                self.transport.loseConnection()
                self.type = None
                break
        if self.type:
            for function in tryagain:
                if not function(self.type):
                    self.transport.loseConnection()
                    self.type = None
                    break
        if self.type:
            self.secure = ISSLTransport(self.transport, None) is not None
            self.data_checker.start(5)
            self.pinger.start(self.factory.servconfig["client_ping_interval"], now=False)
            for server in self.factory.servers.itervalues():
                if server.nearHop == self.factory.name:
                    server.callRemote(ConnectUser, uuid=self.type.uuid, ip=self.type.ip, server=self.factory.name, secure=self.secure, signon=epoch(self.type.signon))

    def dataReceived(self, data):
        if self.dead:
            return
        # Get and store the peer certificate if the client is using SSL and providing a client certificate
        # I don't like handling this here, but twisted does not provide a hook to process it in a better place (e.g.
        # when the SSL handshake is complete); see http://twistedmatrix.com/trac/ticket/6024
        # This will be moved in the future when we can.
        if self.secure and self.transport:
            certificate = self.transport.getPeerCertificate()
            if certificate is not None:
                self.type.setMetadata("server", "certfp", certificate.digest("md5").lower().replace(":", ""))
        # Handle the received data
        for modfunc in self.factory.actions["recvdata"]:
            modfunc(self.type, data)
        self.data += len(data)
        if self.pinger.running:
            self.pinger.reset()
        irc.IRC.dataReceived(self, data)
    
    def checkData(self):
        if self.type:
            self.type.checkData(self.data)
        self.data = 0
    
    def ping(self, intervals):
        timeout = self.factory.servconfig["client_timeout_delay"] + self.factory.servconfig["client_ping_interval"] * (intervals - 1)
        if (now() - self.type.lastpong).total_seconds() > timeout:
            log.msg("Client has stopped responding to PING and is now disconnecting.")
            self.transport.loseConnection()
            self.connectionLost(None)
        elif self.type.lastactivity > self.type.lastpong:
            self.type.lastpong = now()
        else:
            self.sendMessage("PING",":{}".format(self.factory.name))
    
    def handleCommand(self, command, prefix, params):
        log.msg("handleCommand: {!r} {!r} {!r}".format(command, prefix, params))
        return self.type.handleCommand(command, prefix, params)
    
    def sendLine(self, line):
        if self.dead:
            return
        for modfunc in self.factory.actions["senddata"]:
            modfunc(self.type, line)
        log.msg("sendLine: {!r}".format(line))
        return irc.IRC.sendLine(self, line)
        
    def connectionLost(self, reason):
        if self.dead:
            return
        self.dead = True
        self.factory.unregisterProtocol(self)
        if self.type:
            self.type.connectionLost(reason)
        if self.data_checker.running:
            self.data_checker.stop()
        if self.pinger.running:
            self.pinger.stop()
Example #8
0
 def connectionLost(self, reason):
     if self.auth_timer: # cancel the nick change timer if a user quits before changing/identifying
         self.auth_timer.cancel()
         self.auth_timer = None
     IRCUser.connectionLost(self, reason)