def start(self): """ Start TLS negotiation. This checks if the receiving entity requires TLS, the SSL library is available and uses the C{required} and C{wanted} instance variables to determine what to do in the various different cases. For example, if the SSL library is not available, and wanted and required by the user, it raises an exception. However if it is not required by both parties, initialization silently succeeds, moving on to the next step. """ if self.wanted: if ssl is None: if self.required: return defer.fail(TLSNotSupported()) else: return defer.succeed(None) else: pass elif self.xmlstream.features[self.feature].required: return defer.fail(TLSRequired()) else: return defer.succeed(None) self._deferred = defer.Deferred() self.xmlstream.addOnetimeObserver("/proceed", self.onProceed) self.xmlstream.addOnetimeObserver("/failure", self.onFailure) self.xmlstream.send(domish.Element((NS_XMPP_TLS, "starttls"))) return self._deferred
def resolve(self, name, timeout = (1, 3, 11, 45)): """Return a Deferred that will resolve a hostname. """ if not name: # XXX - This is *less than* '::', and will screw up IPv6 servers return defer.succeed('0.0.0.0') if abstract.isIPAddress(name): return defer.succeed(name) return self.resolver.getHostByName(name, timeout)
def resolve(self, name, timeout=(1, 3, 11, 45)): """Return a Deferred that will resolve a hostname. """ if not name: # XXX - This is *less than* '::', and will screw up IPv6 servers return defer.succeed("0.0.0.0") if abstract.isIPAddress(name): return defer.succeed(name) return self.resolver.getHostByName(name, timeout)
def sendGroupMessage(self, text, meta={}): if self.account.client is None: raise locals.OfflineError if meta and meta.get("style", None) == "emote": self.account.client.me(self.name,text) return succeed(text) #standard shmandard, clients don't support plain escaped newlines! for line in string.split(text, '\n'): self.account.client.say(self.name, line) return succeed(text)
def sendGroupMessage(self, text, meta={}): if self.account.client is None: raise locals.OfflineError if meta and meta.get("style", None) == "emote": self.account.client.me(self.name, text) return succeed(text) #standard shmandard, clients don't support plain escaped newlines! for line in string.split(text, '\n'): self.account.client.say(self.name, line) return succeed(text)
def sendGroupMessage(self, text, meta=None): if self.account.client is None: raise locals.OfflineError if meta: if meta.get("style", None) == "emote": text="* "+text+"* " self.account.client.chat_say(self.roomID,html(text)) return succeed(text)
def getAddress(self, userURI): if userURI.host != self.domain: return defer.fail(LookupError("unknown domain")) if self.users.has_key(userURI.username): dc, url = self.users[userURI.username] return defer.succeed(url) else: return defer.fail(LookupError("no such user"))
def sendGroupMessage(self, text, meta=None): if self.account.client is None: raise locals.OfflineError if meta: if meta.get("style", None) == "emote": text = "* " + text + "* " self.account.client.chat_say(self.roomID, html(text)) return succeed(text)
def getHostByName(self, name, timeout=(1, 3, 11, 45)): try: address = socket.gethostbyname(name) except socket.error: msg = "address %r not found" % (name,) err = error.DNSLookupError(msg) return defer.fail(err) else: return defer.succeed(address)
def lookupGroup(self, name): assert isinstance(name, unicode) name = name.lower() try: group = self.groups[name] except KeyError: return defer.fail(failure.Failure(ewords.NoSuchGroup(name))) else: return defer.succeed(group)
def lookupUser(self, name): assert isinstance(name, unicode) name = name.lower() try: user = self.users[name] except KeyError: return defer.fail(failure.Failure(ewords.NoSuchUser(name))) else: return defer.succeed(user)
def sendMessage(self, text, meta=None): if self.account.client is None: raise locals.OfflineError for line in string.split(text, '\n'): if meta and meta.get("style", None) == "emote": self.account.client.ctcpMakeQuery(self.name,[('ACTION', line)]) else: self.account.client.msg(self.name, line) return succeed(text)
def getHostByName(self, name, timeout = (1, 3, 11, 45)): try: address = socket.gethostbyname(name) except socket.error: msg = "address %r not found" % (name,) err = error.DNSLookupError(msg) return defer.fail(err) else: return defer.succeed(address)
def setMetadata(self, meta): self.meta = meta sets = [] for p in self.users.itervalues(): d = defer.maybeDeferred(p.groupMetaUpdate, self, meta) d.addErrback(self._ebUserCall, p=p) sets.append(d) defer.DeferredList(sets).addCallback(self._cbUserCall) return defer.succeed(None)
def _expireRegistration(self, username): try: dc, url = self.users[username] except KeyError: return defer.fail(LookupError("no such user")) else: dc.cancel() del self.users[username] return defer.succeed(Registration(0, url))
def getRegistrationInfo(self, userURI): if userURI.host != self.domain: return defer.fail(LookupError("unknown domain")) if self.users.has_key(userURI.username): dc, url = self.users[userURI.username] return defer.succeed( Registration(int(dc.getTime() - time.time()), url)) else: return defer.fail(LookupError("no such user"))
def sendMessage(self, text, meta=None): if self.account.client is None: raise locals.OfflineError for line in string.split(text, '\n'): if meta and meta.get("style", None) == "emote": self.account.client.ctcpMakeQuery(self.name, [('ACTION', line)]) else: self.account.client.msg(self.name, line) return succeed(text)
def receive(self, sender, recipient, message): assert recipient is self receives = [] for p in self.users.itervalues(): if p is not sender: d = defer.maybeDeferred(p.receive, sender, self, message) d.addErrback(self._ebUserCall, p=p) receives.append(d) defer.DeferredList(receives).addCallback(self._cbUserCall) return defer.succeed(None)
def add(self, user): assert iwords.IChatClient.providedBy(user), "%r is not a chat client" % (user,) if user.name not in self.users: additions = [] self.users[user.name] = user for p in self.users.itervalues(): if p is not user: d = defer.maybeDeferred(p.userJoined, self, user) d.addErrback(self._ebUserCall, p=p) additions.append(d) defer.DeferredList(additions).addCallback(self._cbUserCall) return defer.succeed(None)
def remove(self, user, reason=None): assert reason is None or isinstance(reason, unicode) try: del self.users[user.name] except KeyError: pass else: removals = [] for p in self.users.itervalues(): if p is not user: d = defer.maybeDeferred(p.userLeft, self, user, reason) d.addErrback(self._ebUserCall, p=p) removals.append(d) defer.DeferredList(removals).addCallback(self._cbUserCall) return defer.succeed(None)
def initializeStream(self): """ Perform stream initialization procedures. An L{XmlStream} holds a list of initializer objects in its C{initializers} attribute. This method calls these initializers in order and dispatches the C{STREAM_AUTHD_EVENT} event when the list has been successfully processed. Otherwise it dispatches the C{INIT_FAILED_EVENT} event with the failure. Initializers may return the special L{Reset} object to halt the initialization processing. It signals that the current initializer was successfully processed, but that the XML Stream has been reset. An example is the TLSInitiatingInitializer. """ def remove_first(result): self.xmlstream.initializers.pop(0) return result def do_next(result): """ Take the first initializer and process it. On success, the initializer is removed from the list and then next initializer will be tried. """ if result is Reset: return None try: init = self.xmlstream.initializers[0] except IndexError: self.xmlstream.dispatch(self.xmlstream, STREAM_AUTHD_EVENT) return None else: d = defer.maybeDeferred(init.initialize) d.addCallback(remove_first) d.addCallback(do_next) return d d = defer.succeed(None) d.addCallback(do_next) d.addErrback(self.xmlstream.dispatch, INIT_FAILED_EVENT)
def sync(self): """Commit changes to database.""" if self.syncing: raise ValueError, "sync already in progress" comandMap = {INSERT : self.reflector.insertRowSQL, UPDATE : self.reflector.updateRowSQL, DELETE : self.reflector.deleteRowSQL} sqlCommands = [] for kind, obj in self.commands: sqlCommands.append(comandMap[kind](obj)) self.commands = [] if sqlCommands: self.syncing = 1 d = self.reflector.dbpool.runInteraction(self._sync, self.latestIndex, sqlCommands) d.addCallback(self._syncDone) return d else: return defer.succeed(1)
def registerAddress(self, domainURL, logicalURL, physicalURL): if domainURL.host != self.domain: log.msg("Registration for domain we don't handle.") return defer.fail(RegistrationError(404)) if logicalURL.host != self.domain: log.msg("Registration for domain we don't handle.") return defer.fail(RegistrationError(404)) if self.users.has_key(logicalURL.username): dc, old = self.users[logicalURL.username] dc.reset(3600) else: dc = reactor.callLater(3600, self._expireRegistration, logicalURL.username) log.msg("Registered %s at %s" % (logicalURL.toString(), physicalURL.toString())) self.users[logicalURL.username] = (dc, physicalURL) return defer.succeed( Registration(int(dc.getTime() - time.time()), physicalURL))
def sync(self): """Commit changes to database.""" if self.syncing: raise ValueError, "sync already in progress" comandMap = { INSERT: self.reflector.insertRowSQL, UPDATE: self.reflector.updateRowSQL, DELETE: self.reflector.deleteRowSQL } sqlCommands = [] for kind, obj in self.commands: sqlCommands.append(comandMap[kind](obj)) self.commands = [] if sqlCommands: self.syncing = 1 d = self.reflector.dbpool.runInteraction(self._sync, self.latestIndex, sqlCommands) d.addCallback(self._syncDone) return d else: return defer.succeed(1)
def _loopbackAsyncBody(server, serverToClient, client, clientToServer, pumpPolicy): """ Transfer bytes from the output queue of each protocol to the input of the other. @param server: The protocol instance representing the server-side of this connection. @param serverToClient: The L{_LoopbackQueue} holding the server's output. @param client: The protocol instance representing the client-side of this connection. @param clientToServer: The L{_LoopbackQueue} holding the client's output. @param pumpPolicy: See L{loopbackAsync}. @return: A L{Deferred} which fires when the connection has been closed and both sides have received notification of this. """ def pump(source, q, target): sent = False if q: pumpPolicy(q, target) sent = True if sent and not q: # A write buffer has now been emptied. Give any producer on that # side an opportunity to produce more data. source.transport._pollProducer() return sent while 1: disconnect = clientSent = serverSent = False # Deliver the data which has been written. serverSent = pump(server, serverToClient, client) clientSent = pump(client, clientToServer, server) if not clientSent and not serverSent: # Neither side wrote any data. Wait for some new data to be added # before trying to do anything further. d = defer.Deferred() clientToServer._notificationDeferred = d serverToClient._notificationDeferred = d d.addCallback(_loopbackAsyncContinue, server, serverToClient, client, clientToServer, pumpPolicy) return d if serverToClient.disconnect: # The server wants to drop the connection. Flush any remaining # data it has. disconnect = True pump(server, serverToClient, client) elif clientToServer.disconnect: # The client wants to drop the connection. Flush any remaining # data it has. disconnect = True pump(client, clientToServer, server) if disconnect: # Someone wanted to disconnect, so okay, the connection is gone. server.connectionLost(failure.Failure(main.CONNECTION_DONE)) client.connectionLost(failure.Failure(main.CONNECTION_DONE)) return defer.succeed(None)
def get(self, key): return defer.succeed(self.data.get(key))
def logCommand(self, command, time): """Log a command.""" self.currentIndex += 1 self.db[str(self.currentIndex)] = (time, command) return defer.succeed(1)
def _loopbackAsyncBody(server, serverToClient, client, clientToServer, pumpPolicy): """ Transfer bytes from the output queue of each protocol to the input of the other. @param server: The protocol instance representing the server-side of this connection. @param serverToClient: The L{_LoopbackQueue} holding the server's output. @param client: The protocol instance representing the client-side of this connection. @param clientToServer: The L{_LoopbackQueue} holding the client's output. @param pumpPolicy: See L{loopbackAsync}. @return: A L{Deferred} which fires when the connection has been closed and both sides have received notification of this. """ def pump(source, q, target): sent = False if q: pumpPolicy(q, target) sent = True if sent and not q: # A write buffer has now been emptied. Give any producer on that # side an opportunity to produce more data. source.transport._pollProducer() return sent while 1: disconnect = clientSent = serverSent = False # Deliver the data which has been written. serverSent = pump(server, serverToClient, client) clientSent = pump(client, clientToServer, server) if not clientSent and not serverSent: # Neither side wrote any data. Wait for some new data to be added # before trying to do anything further. d = defer.Deferred() clientToServer._notificationDeferred = d serverToClient._notificationDeferred = d d.addCallback( _loopbackAsyncContinue, server, serverToClient, client, clientToServer, pumpPolicy) return d if serverToClient.disconnect: # The server wants to drop the connection. Flush any remaining # data it has. disconnect = True pump(server, serverToClient, client) elif clientToServer.disconnect: # The client wants to drop the connection. Flush any remaining # data it has. disconnect = True pump(client, clientToServer, server) if disconnect: # Someone wanted to disconnect, so okay, the connection is gone. server.connectionLost(failure.Failure(main.CONNECTION_DONE)) client.connectionLost(failure.Failure(main.CONNECTION_DONE)) return defer.succeed(None)
def itergroups(self): return defer.succeed(self.groups.itervalues())
def addUser(self, user): if user.name in self.users: return defer.fail(failure.Failure(ewords.DuplicateUser())) self.users[user.name] = user return defer.succeed(user)
def addGroup(self, group): if group.name in self.groups: return defer.fail(failure.Failure(ewords.DuplicateGroup())) self.groups[group.name] = group return defer.succeed(group)
def size(self): return defer.succeed(len(self.users))
def listenClass(self, port, klass, *args): serv = reactor.listenTCP(port, klass(*args)) return defer.succeed(serv.getHost()[1:])