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 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"))
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()
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"))
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)
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)
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()
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)