def sendInvitations(self): if config.enableAutoInvite: for jid in self.xdb.getRegistrationList(): LogEvent(INFO, msg="Inviting %r" % jid) jabw.sendPresence(self, jid, config.jid, ptype="probe") jabw.sendPresence(self, jid, "%s/registered" % (config.jid), ptype="probe")
class RegisterManager: def __init__(self, pytrans): self.pytrans = pytrans if config.allowRegister: self.pytrans.discovery.addFeature(disco.IQREGISTER, self.incomingRegisterIq, config.jid) LogEvent(INFO) def removeRegInfo(self, jabberID): LogEvent(INFO) try: # If the session is active then send offline presences session = self.pytrans.sessions[jabberID] session.removeMe() except KeyError: pass self.pytrans.xdb.remove(jabberID) LogEvent(INFO, "", "done") def setRegInfo(self, jabberID, username, password): LogEvent(INFO) if (len(password) == 0): (blah1, password, blah3) = self.getRegInfo(jabberID) reginfo = legacy.formRegEntry(username, password) self.pytrans.xdb.set( internJID(jabberID).userhost(), legacy.namespace, reginfo) def getRegInfo(self, jabberID): LogEvent(INFO) result = self.pytrans.xdb.request( internJID(jabberID).userhost(), legacy.namespace) if (result == None): LogEvent(INFO, "", "Not registered!") return None username, password = legacy.getAttributes(result) if (username and password and len(username) > 0 and len(password) > 0): LogEvent(INFO, "", "Returning reg info.") return (username, password) else: LogEvent(WARN, "", "Registration data corrupted!") return None def incomingRegisterIq(self, incoming): # Check what type the Iq is.. itype = incoming.getAttribute("type") LogEvent(INFO) if (itype == "get"): self.sendRegistrationFields(incoming) elif (itype == "set"): self.updateRegistration(incoming) def sendRegistrationFields(self, incoming): # Construct a reply with the fields they must fill out ID = incoming.getAttribute("id") fro = incoming.getAttribute("from") LogEvent(INFO) reply = Element((None, "iq")) reply.attributes["from"] = config.jid reply.attributes["to"] = fro if ID: reply.attributes["id"] = ID reply.attributes["type"] = "result" query = reply.addElement("query") query.attributes["xmlns"] = "jabber:iq:register" instructions = query.addElement("instructions") ulang = utils.getLang(incoming) instructions.addContent(lang.get(ulang).registerText) userEl = query.addElement("username") passEl = query.addElement("password") # Check to see if they're registered result = self.getRegInfo(incoming.getAttribute("from")) if (result): username, password = result userEl.addContent(username) query.addElement("registered") self.pytrans.send(reply) def updateRegistration(self, incoming): # Grab the username, password ID = incoming.getAttribute("id") fro = incoming.getAttribute("from") LogEvent(INFO) source = internJID(fro).userhost() ulang = utils.getLang(incoming) username = None password = None for queryFind in incoming.elements(): if (queryFind.name == "query"): for child in queryFind.elements(): try: if (child.name == "username"): username = child.__str__() elif (child.name == "password"): password = child.__str__() elif (child.name == "remove"): # The user wants to unregister the transport! Gasp! LogEvent(INFO, "", "Unregistering.") try: self.removeRegInfo(source) self.successReply(incoming) except: self.xdbErrorReply(incoming) return LogEvent(INFO, "", "Unregistered!") return except AttributeError, TypeError: continue # Ignore any errors, we'll check everything below if (self.isValid(username) and password and len(username) > 0 and len(password) > 0): # Valid registration data LogEvent(INFO, "", "Updating XDB") try: self.setRegInfo(source, username, password) LogEvent(INFO, "", "Updated XDB") self.successReply(incoming) LogEvent(INFO, "", "Sent a result Iq") to = internJID(incoming.getAttribute("from")).userhost() jabw.sendPresence(self.pytrans, to=to, fro=config.jid, ptype="subscribe") if (config.registerMessage): jabw.sendMessage(self.pytrans, to=incoming.getAttribute("from"), fro=config.jid, body=config.registerMessage) except: self.xdbErrorReply(incoming) raise else: self.badRequestReply(incoming)
return LogEvent(INFO, msg="Unregistered!") return except AttributeError, TypeError: continue # Ignore any errors, we'll check everything below if username and password and len(username) > 0 and len(password) > 0: # Valid registration data LogEvent(INFO, msg="Updating XDB") try: self.pytrans.xdb.setRegistration(source, username, password) LogEvent(INFO, msg="Updated XDB") self.successReply(incoming) LogEvent(INFO, msg="Sent a result Iq") to = internJID(incoming.getAttribute("from")).userhost() jabw.sendPresence(self.pytrans, to=to, fro=config.jid, ptype="subscribe") if config.registerMessage: jabw.sendMessage(self.pytrans, to=incoming.getAttribute("from"), fro=config.jid, body=config.registerMessage) except: self.xdbErrorReply(incoming) raise else: self.badRequestReply(incoming) def badRequestReply(self, incoming): LogEvent(INFO) # Send an error Iq reply = incoming reply.swapAttributeValues("to", "from") reply.attributes["type"] = "error"
def sendProbes(self): for jid in self.pytrans.xdb.getRegistrationList(): jabw.sendPresence(self.pytrans, jid, config.jid, ptype="probe")
class PyTransport(component.Service): def __init__(self): LogEvent(INFO) LogEvent(INFO, msg="Reactor: " + str(reactor)) # Discovery, as well as some builtin features self.discovery = disco.ServerDiscovery(self) self.discovery.addIdentity("gateway", legacy.id, config.discoName, config.jid) self.discovery.addIdentity("conference", "text", config.discoName + " Chatrooms", config.jid) self.discovery.addFeature( disco.XCONFERENCE, None, config.jid ) # So that clients know you can create groupchat rooms on the server self.discovery.addFeature( "jabber:iq:conference", None, config.jid ) # We don't actually support this, but Psi has a bug where it looks for this instead of the above self.discovery.addIdentity("client", "pc", "MSN Messenger", "USER") self.discovery.addIdentity("conference", "text", "MSN Groupchat", "ROOM") self.xdb = xdb.XDB(config.jid, legacy.mangle) self.avatarCache = avatar.AvatarCache() self.registermanager = register.RegisterManager(self) self.gatewayTranslator = misciq.GatewayTranslator(self) self.versionTeller = misciq.VersionTeller(self) self.pingService = misciq.PingService(self) self.adHocCommands = misciq.AdHocCommands(self) self.vCardFactory = misciq.VCardFactory(self) self.iqAvatarFactor = misciq.IqAvatarFactory(self) self.connectUsers = misciq.ConnectUsers(self) if config.ftJabberPort: self.ftSOCKS5Receive = ft.Proxy65(int(config.ftJabberPort)) self.ftSOCKS5Send = misciq.Socks5FileTransfer(self) if config.ftOOBPort: self.ftOOBReceive = ft.FileTransferOOBReceive(int( config.ftOOBPort)) self.ftOOBSend = misciq.FileTransferOOBSend(self) self.statistics = misciq.Statistics(self) self.startTime = int(time.time()) self.xmlstream = None self.sessions = {} # Groupchat ID handling self.lastID = 0 self.reservedIDs = [] # Message IDs self.messageID = 0 self.loopTask = task.LoopingCall(self.loopFunc) self.loopTask.start(60.0) def removeMe(self): LogEvent(INFO) for session in self.sessions.copy(): self.sessions[session].removeMe() def makeMessageID(self): self.messageID += 1 return str(self.messageID) def makeID(self): newID = "r" + str(self.lastID) self.lastID += 1 if self.reservedIDs.count(newID) > 0: # Ack, it's already used.. Try again return self.makeID() else: return newID def reserveID(self, ID): self.reservedIDs.append(ID) def loopFunc(self): numsessions = len(self.sessions) #if config.debugOn and numsessions > 0: # print "Sessions:" # for key in self.sessions: # print "\t" + self.sessions[key].jabberID self.statistics.stats["Uptime"] = int(time.time()) - self.startTime self.statistics.stats["OnlineUsers"] = numsessions legacy.updateStats(self.statistics) if numsessions > 0: oldDict = self.sessions.copy() self.sessions = {} for key in oldDict: s = oldDict[key] if not s.alive: LogEvent(WARN, "", "Ghost session found.") # Don't add it to the new dictionary. Effectively removing it else: self.sessions[key] = s def componentConnected(self, xmlstream): LogEvent(INFO) self.xmlstream = xmlstream self.xmlstream.addObserver("/iq", self.discovery.onIq) self.xmlstream.addObserver("/presence", self.onPresence) self.xmlstream.addObserver("/message", self.onMessage) self.xmlstream.addObserver("/route", self.onRouteMessage) if config.useXCP: pres = Element((None, "presence")) pres.attributes["to"] = "presence@-internal" pres.attributes["from"] = config.compjid x = pres.addElement("x") x.attributes[ "xmlns"] = "http://www.jabber.com/schemas/component-presence.xsd" x.attributes["xmlns:config"] = "http://www.jabber.com/config" x.attributes["config:version"] = "1" x.attributes["protocol-version"] = "1.0" x.attributes["config-ns"] = legacy.url + "/component" self.send(pres) def componentDisconnected(self): LogEvent(INFO) self.xmlstream = None def onRouteMessage(self, el): for child in el.elements(): if child.name == "message": self.onMessage(child) elif child.name == "presence": # Ignore any presence broadcasts about other XCP components if child.getAttribute("to") and child.getAttribute("to").find( "@-internal") > 0: return self.onPresence(child) elif child.name == "iq": self.discovery.onIq(child) def onMessage(self, el): fro = el.getAttribute("from") try: froj = internJID(fro) except Exception, e: LogEvent(WARN, "", "Failed stringprep.") return mtype = el.getAttribute("type") s = self.sessions.get(froj.userhost(), None) if mtype == "error" and s: LogEvent(INFO, s.jabberID, "Removing session because of message type=error") s.removeMe() elif s: s.onMessage(el) elif mtype != "error": to = el.getAttribute("to") ulang = utils.getLang(el) body = None for child in el.elements(): if child.name == "body": body = child.__str__() LogEvent( INFO, "", "Sending error response to a message outside of session.") jabw.sendErrorMessage(self, fro, to, "auth", "not-authorized", lang.get(ulang).notLoggedIn, body) jabw.sendPresence(self, fro, to, ptype="unavailable")
self.sessions[froj.userhost()] = s LogEvent(INFO, "", "New session created.") # Send the first presence s.onPresence(el) else: LogEvent(INFO, "", "Failed to create session") jabw.sendMessage(self, to=froj.userhost(), fro=config.jid, body=lang.get(ulang).notRegistered) elif el.getAttribute("type") != "error": LogEvent( INFO, "", "Sending unavailable presence to non-logged in user.") jabw.sendPresence(self, fro, to, ptype="unavailable") return elif ptype and (ptype.startswith("subscribe") or ptype.startswith("unsubscribe")): # They haven't logged in, and are trying to change subscription to a user # No, lets not log them in. Lets send an error :) jabw.sendPresence(self, fro, to, ptype="error") # Lets log them in and then do it #LogEvent(INFO, "", "Attempting to create a session to do subscription stuff.") #s = session.makeSession(self, froj.userhost(), ulang) #if s: # self.sessions[froj.userhost()] = s # LogEvent(INFO, "", "New session created.") # # Tell the session there's a new resource
def sendProbes(self): for jid in self.pytrans.xdb.files(): jabw.sendPresence(self.pytrans, jid, config.jid, ptype="probe")
LogEvent(INFO, msg="Unregistered!") return except AttributeError, TypeError: continue # Ignore any errors, we'll check everything below if username and password and len(username) > 0 and len(password) > 0: # Valid registration data LogEvent(INFO, msg="Updating XDB") try: self.pytrans.xdb.setRegistration(source, username, password) LogEvent(INFO, msg="Updated XDB") self.successReply(incoming) LogEvent(INFO, msg="Sent a result Iq") to = internJID(incoming.getAttribute("from")).userhost() jabw.sendPresence(self.pytrans, to=to, fro=config.jid, ptype="subscribe") if config.registerMessage: jabw.sendMessage(self.pytrans, to=incoming.getAttribute("from"), fro=config.jid, body=config.registerMessage) except: self.xdbErrorReply(incoming) raise else: self.badRequestReply(incoming) def badRequestReply(self, incoming): LogEvent(INFO)